From 3126128f71edefb17d9ea2c4be634689e07de4a8 Mon Sep 17 00:00:00 2001 From: julien Date: Fri, 21 Dec 2018 10:01:13 +0100 Subject: [PATCH 01/42] Create node action in context menu working --- .../DocumentNodeTreeAjaxController.php | 37 +++++++++++- .../Form/Handler/DocumentHandler.php | 1 + .../JsTree/DocumentNodeUpdateTreeHandler.php | 49 +++++++++++++++- .../Resources/config/controllers.yml | 2 + src/DAMBundle/Resources/config/services.yml | 2 + .../public/js/app/views/tree-manage-view.js | 58 ++++++++++++++++++- .../Resources/translations/jsmessages.en.yml | 4 +- .../translations/jsmessages.fr_FR.yml | 4 +- 8 files changed, 150 insertions(+), 7 deletions(-) diff --git a/src/DAMBundle/Controller/DocumentNodeTreeAjaxController.php b/src/DAMBundle/Controller/DocumentNodeTreeAjaxController.php index 91cda17..8f79c3e 100644 --- a/src/DAMBundle/Controller/DocumentNodeTreeAjaxController.php +++ b/src/DAMBundle/Controller/DocumentNodeTreeAjaxController.php @@ -6,6 +6,7 @@ use Doctrine\ORM\EntityManager; use Doctrine\ORM\ORMException; use Kiboko\Bundle\DAMBundle\Entity\DocumentNode; +use Kiboko\Bundle\DAMBundle\JsTree\DocumentNodeUpdateTreeHandler; use Kiboko\Bundle\DAMBundle\Model\DocumentNodeInterface; use Oro\Bundle\LocaleBundle\Helper\LocalizationHelper; use Sensio\Bundle\FrameworkExtraBundle\Configuration\Method; @@ -27,16 +28,23 @@ class DocumentNodeTreeAjaxController extends Controller /** @var LocalizationHelper */ private $localizationHelper; + /** @var DocumentNodeUpdateTreeHandler */ + private $handler; + /** * @param EntityManager $em * @param LocalizationHelper $localizationHelper + * @param DocumentNodeUpdateTreeHandler $handler */ public function __construct( EntityManager $em, - LocalizationHelper $localizationHelper + LocalizationHelper $localizationHelper, + DocumentNodeUpdateTreeHandler $handler + ) { $this->em = $em; $this->localizationHelper = $localizationHelper; + $this->handler = $handler; } @@ -122,6 +130,33 @@ public function renameAction(Request $request, DocumentNodeInterface $node) return new JsonResponse('renamed',200); } + /** + * @Route("/create/{uuid}", + * name="kiboko_dam_document_node_tree_ajax_create", + * requirements={"uuid"="[\da-f]{8}-[\da-f]{4}-[\da-f]{4}-[\da-f]{4}-[\da-f]{12}"}, + * options={ + * "expose"=true, + * }, + * ) + * @ParamConverter("node", + * class="KibokoDAMBundle:DocumentNode", + * options={ + * "mapping": { + * "uuid": "uuid", + * }, + * "map_method_signature" = true, + * } + * ) + * @Method({"POST"}) + * + * {@inheritdoc} + */ + public function createNodeAction(Request $request, DocumentNodeInterface $node) + { + $name= $request->get('name'); + return $this->handler->createNode($node,$name); + } + /** * @Route("/move/{uuid}", * name="kiboko_dam_document_node_tree_ajax_move", diff --git a/src/DAMBundle/Form/Handler/DocumentHandler.php b/src/DAMBundle/Form/Handler/DocumentHandler.php index 348bb53..9f60da9 100644 --- a/src/DAMBundle/Form/Handler/DocumentHandler.php +++ b/src/DAMBundle/Form/Handler/DocumentHandler.php @@ -44,6 +44,7 @@ public function __construct(FormInterface $form, RequestStack $requestStack, Ent */ public function process(Document $entity, DocumentNodeInterface $node) { + //FIXME:: Implement FormHandlerInterface $entity->setNode($node); $this->form->setData($entity); diff --git a/src/DAMBundle/JsTree/DocumentNodeUpdateTreeHandler.php b/src/DAMBundle/JsTree/DocumentNodeUpdateTreeHandler.php index 5860e91..d26073a 100644 --- a/src/DAMBundle/JsTree/DocumentNodeUpdateTreeHandler.php +++ b/src/DAMBundle/JsTree/DocumentNodeUpdateTreeHandler.php @@ -2,10 +2,17 @@ namespace Kiboko\Bundle\DAMBundle\JsTree; +use Doctrine\Common\Collections\ArrayCollection; +use Doctrine\ORM\EntityManager; +use Doctrine\ORM\ORMException; +use Kiboko\Bundle\DAMBundle\Entity\DocumentNode; use Kiboko\Bundle\DAMBundle\Entity\TeamStorageNode; use Kiboko\Bundle\DAMBundle\Model\DocumentNodeInterface; +use Oro\Bundle\LocaleBundle\Entity\LocalizedFallbackValue; use Oro\Bundle\LocaleBundle\Helper\LocalizationHelper; use Oro\Bundle\UIBundle\Model\TreeItem; +use Symfony\Component\HttpFoundation\JsonResponse; +use Symfony\Component\HttpFoundation\Request; use Symfony\Component\Translation\TranslatorInterface; class DocumentNodeUpdateTreeHandler @@ -22,16 +29,24 @@ class DocumentNodeUpdateTreeHandler */ private $localizationHelper; + /** + * @var EntityManager + */ + private $entityManager; + /** * @param TranslatorInterface $translator - * @param LocalizationHelper $localizationHelper + * @param LocalizationHelper $localizationHelper + * @param EntityManager $entityManager */ public function __construct( TranslatorInterface $translator, - LocalizationHelper $localizationHelper + LocalizationHelper $localizationHelper, + EntityManager $entityManager ) { $this->translator = $translator; $this->localizationHelper = $localizationHelper; + $this->entityManager = $entityManager; } /** @@ -168,4 +183,34 @@ public function disableTreeItems(array $sourceData, array &$treeData) } } } + + public function createNode(DocumentNodeInterface $parent,string $name) { + + $node = new DocumentNode(); + $node->setParent($parent); + + $nameToApply = new LocalizedFallbackValue(); + $nameToApply->setString($name); + $nameToApply->setLocalization($this->localizationHelper->getCurrentLocalization()); + + $names = new ArrayCollection(); + $names->add($nameToApply); + + $slugs = new ArrayCollection(); + $slugs->add($nameToApply); + + $node->setNames($names); + $node->setSlugs($slugs); + + try { + $this->entityManager->persist($node); + $this->entityManager->flush(); + } + catch (ORMException $e) { + return new JsonResponse($e->getMessage(),500); + } + + return new JsonResponse('created',200); + + } } diff --git a/src/DAMBundle/Resources/config/controllers.yml b/src/DAMBundle/Resources/config/controllers.yml index 6b1141f..e92c642 100644 --- a/src/DAMBundle/Resources/config/controllers.yml +++ b/src/DAMBundle/Resources/config/controllers.yml @@ -4,6 +4,8 @@ services: arguments: - '@doctrine.orm.entity_manager' - '@oro_locale.helper.localization' + - '@kiboko_dam.tree.document_node_update_tree_handler' + calls: - [setContainer, ["@service_container"]] diff --git a/src/DAMBundle/Resources/config/services.yml b/src/DAMBundle/Resources/config/services.yml index 2536aa6..342ee6c 100644 --- a/src/DAMBundle/Resources/config/services.yml +++ b/src/DAMBundle/Resources/config/services.yml @@ -48,6 +48,8 @@ services: arguments: - '@translator' - '@oro_locale.helper.localization' + - '@doctrine.orm.entity_manager' + kiboko_dam.controller.document_node: class: Kiboko\Bundle\DAMBundle\Controller\DocumentNodeController diff --git a/src/DAMBundle/Resources/public/js/app/views/tree-manage-view.js b/src/DAMBundle/Resources/public/js/app/views/tree-manage-view.js index 40029fd..7c50963 100644 --- a/src/DAMBundle/Resources/public/js/app/views/tree-manage-view.js +++ b/src/DAMBundle/Resources/public/js/app/views/tree-manage-view.js @@ -17,6 +17,11 @@ define(function(require) { * @class kibokodam.app.components.TreeManageView */ TreeManageView = BaseTreeManageView.extend({ + + formatUuuid: function(chain) { + return chain.substr(5).replace(/_/g, '-'); + }, + /** * @inheritDoc */ @@ -25,7 +30,7 @@ define(function(require) { }, treeEvents: { - 'create_node.jstree': 'onCreate', + 'create_node.jstree': 'onNodeCreate', 'rename_node.jstree': 'onNodeNameChange', 'delete_node.jstree': 'onNodeDelete', 'move_node.jstree': 'onNodeMove', @@ -48,7 +53,6 @@ define(function(require) { url: url }); }, - /** * Triggers after node deleted in tree * @@ -93,6 +97,28 @@ define(function(require) { }); } }, + /** + * Triggers after node change creation + * + * @param {Event} e + * @param {Object} data + */ + onNodeCreate: function(e, data) { + var parent = data.parent; + var name = data.node.original.text; + + if (data.node.original.uuid !== '') { + var url = routing.generate('kiboko_dam_document_node_tree_ajax_create', {uuid: this.formatUuuid(parent)}); + $.ajax({ + async: false, + type: 'POST', + data: { + 'name': name, + }, + url: url + }); + } + }, /** * Triggers after node selection in tree @@ -175,6 +201,34 @@ define(function(require) { this.edit($node); }).bind(tree) }, + "Create": { + "separator_before": false, + "separator_after": true, + "label": "Create", + "action": false, + "submenu": { + "File": { + "seperator_before": false, + "seperator_after": false, + "label": "File", + action: function (obj) { + tree.create_node($node, { type: 'file', text: _.__('kiboko.dam.js.jstree.contextmenu.newfile.label'),icon: 'glyphicon glyphicon-file' }); + tree.deselect_all(); + tree.select_node($node); + } + }, + "Folder": { + "seperator_before": false, + "seperator_after": false, + "label": "Folder", + action: function (data) { + tree.create_node($node, { text: _.__('kiboko.dam.js.jstree.contextmenu.newfile.label'), type: 'default' }); + tree.deselect_all(); + tree.select_node($node); + } + }, + } + }, "Remove": { "separator_before": false, "separator_after": false, diff --git a/src/DAMBundle/Resources/translations/jsmessages.en.yml b/src/DAMBundle/Resources/translations/jsmessages.en.yml index ff70eee..3e4f0d4 100644 --- a/src/DAMBundle/Resources/translations/jsmessages.en.yml +++ b/src/DAMBundle/Resources/translations/jsmessages.en.yml @@ -6,4 +6,6 @@ kiboko: rename: label: Rename delete: - label: Delete \ No newline at end of file + label: Delete + newfile: + label: New folder \ No newline at end of file diff --git a/src/DAMBundle/Resources/translations/jsmessages.fr_FR.yml b/src/DAMBundle/Resources/translations/jsmessages.fr_FR.yml index 9ae7442..ca2f67b 100644 --- a/src/DAMBundle/Resources/translations/jsmessages.fr_FR.yml +++ b/src/DAMBundle/Resources/translations/jsmessages.fr_FR.yml @@ -6,4 +6,6 @@ kiboko: rename: label: Renommer delete: - label: Supprimer \ No newline at end of file + label: Supprimer + newfile: + label: Nouveau fichier \ No newline at end of file From 82add844294639f683a9808a6994333150d62493 Mon Sep 17 00:00:00 2001 From: julien Date: Mon, 24 Dec 2018 10:02:33 +0100 Subject: [PATCH 02/42] Added datagrid with parameters reloading in document tree view --- .../DocumentDatagridListener.php | 40 +++++++++++++++++++ .../Resources/config/oro/datagrids.yml | 5 ++- src/DAMBundle/Resources/config/services.yml | 8 ++++ .../public/js/app/views/tree-manage-view.js | 22 ++++++++-- 4 files changed, 71 insertions(+), 4 deletions(-) create mode 100644 src/DAMBundle/EventListener/DocumentDatagridListener.php diff --git a/src/DAMBundle/EventListener/DocumentDatagridListener.php b/src/DAMBundle/EventListener/DocumentDatagridListener.php new file mode 100644 index 0000000..94b95f7 --- /dev/null +++ b/src/DAMBundle/EventListener/DocumentDatagridListener.php @@ -0,0 +1,40 @@ +em = $em; + } + + /** + * + * @param BuildBefore $event + */ + public function onBuildBefore(BuildBefore $event) + { + if( $event->getDatagrid()->getParameters()->get('_parameters')) + { + $uuid = $event->getDatagrid()->getParameters()->get('_parameters'); + $uuid = $uuid['parent']; + + $node = $this->em->getRepository(DocumentNode::class)->findOneBy(['uuid' => $uuid]); + $event->getDatagrid()->getParameters()->set('parent', $node->getUuid()); + } + } +} diff --git a/src/DAMBundle/Resources/config/oro/datagrids.yml b/src/DAMBundle/Resources/config/oro/datagrids.yml index 28bcfb8..69cfd52 100644 --- a/src/DAMBundle/Resources/config/oro/datagrids.yml +++ b/src/DAMBundle/Resources/config/oro/datagrids.yml @@ -134,7 +134,10 @@ datagrids: and: - node.uuid = :parent bind_parameters: - parent: parent + - + name: parent + default: null + type: string properties: name: type: localized_value diff --git a/src/DAMBundle/Resources/config/services.yml b/src/DAMBundle/Resources/config/services.yml index 342ee6c..70927c9 100644 --- a/src/DAMBundle/Resources/config/services.yml +++ b/src/DAMBundle/Resources/config/services.yml @@ -91,3 +91,11 @@ services: - '@oro_featuretoggle.checker.feature_checker' tags: - { name: kernel.event_listener, event: oro_menu.configure.application_menu, method: onNavigationConfigure } + + kiboko_dam.event_listener.document_datagrid: + class: Kiboko\Bundle\DAMBundle\EventListener\DocumentDatagridListener + arguments: + - '@doctrine.orm.entity_manager' + tags: + - { name: kernel.event_listener, event: oro_datagrid.datagrid.build.before.kiboko-dam-documents-grid, method: onBuildBefore } + diff --git a/src/DAMBundle/Resources/public/js/app/views/tree-manage-view.js b/src/DAMBundle/Resources/public/js/app/views/tree-manage-view.js index 7c50963..f0c36fd 100644 --- a/src/DAMBundle/Resources/public/js/app/views/tree-manage-view.js +++ b/src/DAMBundle/Resources/public/js/app/views/tree-manage-view.js @@ -34,6 +34,8 @@ define(function(require) { 'rename_node.jstree': 'onNodeNameChange', 'delete_node.jstree': 'onNodeDelete', 'move_node.jstree': 'onNodeMove', + 'select_node.jstree': 'onNodeOpen', + }, /** @@ -53,6 +55,17 @@ define(function(require) { url: url }); }, + /** + * Triggers after node is opened + * + * @param {Event} e + * @param {Object} data + */ + onNodeOpen: function(e, data) { + + mediator.trigger('datagrid:setParam:' + 'kiboko-dam-documents-grid', 'parent', this.formatUuuid(data.node.original.id)); + mediator.trigger('datagrid:doRefresh:' + 'kiboko-dam-documents-grid'); + }, /** * Triggers after node deleted in tree * @@ -84,6 +97,7 @@ define(function(require) { */ onNodeNameChange: function(e, data) { var uuid = data.node.original.uuid; + var name = data.text; if (data.node.original.uuid !== '') { var url = routing.generate('kiboko_dam_document_node_tree_ajax_rename', {uuid: uuid}); @@ -104,6 +118,7 @@ define(function(require) { * @param {Object} data */ onNodeCreate: function(e, data) { + console.log("YOP"); var parent = data.parent; var name = data.node.original.text; @@ -157,6 +172,9 @@ define(function(require) { */ customizeTreeConfig: function(options, config) { + config.root = { + "valid_children" : ["default"], + } if (this.checkboxEnabled) { config.plugins.push('checkbox'); config.plugins.push('contextmenu'); @@ -212,9 +230,7 @@ define(function(require) { "seperator_after": false, "label": "File", action: function (obj) { - tree.create_node($node, { type: 'file', text: _.__('kiboko.dam.js.jstree.contextmenu.newfile.label'),icon: 'glyphicon glyphicon-file' }); - tree.deselect_all(); - tree.select_node($node); + //TO:DO upload widget } }, "Folder": { From 313509fb1b2b8c95cff3e506a0e80f7696c3f16d Mon Sep 17 00:00:00 2001 From: julien Date: Mon, 24 Dec 2018 10:04:35 +0100 Subject: [PATCH 03/42] Changed formating of js tree data to add the top level root node ( node tree interface ) to be able to create a node in the root dir with contextMenu --- src/DAMBundle/JsTree/DocumentNodeUpdateTreeHandler.php | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/src/DAMBundle/JsTree/DocumentNodeUpdateTreeHandler.php b/src/DAMBundle/JsTree/DocumentNodeUpdateTreeHandler.php index d26073a..879ebb6 100644 --- a/src/DAMBundle/JsTree/DocumentNodeUpdateTreeHandler.php +++ b/src/DAMBundle/JsTree/DocumentNodeUpdateTreeHandler.php @@ -96,13 +96,13 @@ private function formatTree(array $entities, DocumentNodeInterface $root) foreach ($entities as $entity) { $node = $this->formatEntity($root, $entity); - if ($entity->getParent() === $root) { - $node['parent'] = self::ROOT_PARENT_VALUE; - } - $formattedTree[] = $node; } + $topNode = $this->formatEntity($root,$root); + $topNode['parent'] = self::ROOT_PARENT_VALUE; + $formattedTree[] = $topNode; + return $formattedTree; } From 66b8e42a5859486fa593c2442f27f120b4569969 Mon Sep 17 00:00:00 2001 From: julien Date: Mon, 24 Dec 2018 10:38:07 +0100 Subject: [PATCH 04/42] Fix to prevent creating folder with a name already used using the contextMenu of JsTree --- .../public/js/app/views/tree-manage-view.js | 37 ++++++++++++------- 1 file changed, 24 insertions(+), 13 deletions(-) diff --git a/src/DAMBundle/Resources/public/js/app/views/tree-manage-view.js b/src/DAMBundle/Resources/public/js/app/views/tree-manage-view.js index f0c36fd..2256773 100644 --- a/src/DAMBundle/Resources/public/js/app/views/tree-manage-view.js +++ b/src/DAMBundle/Resources/public/js/app/views/tree-manage-view.js @@ -97,18 +97,20 @@ define(function(require) { */ onNodeNameChange: function(e, data) { var uuid = data.node.original.uuid; - - var name = data.text; - if (data.node.original.uuid !== '') { - var url = routing.generate('kiboko_dam_document_node_tree_ajax_rename', {uuid: uuid}); - $.ajax({ - async: false, - type: 'POST', - data: { - 'newName': name - }, - url: url - }); + if (uuid) { + console.log(uuid); + var name = data.text; + if (data.node.original.uuid !== '') { + var url = routing.generate('kiboko_dam_document_node_tree_ajax_rename', {uuid: uuid}); + $.ajax({ + async: false, + type: 'POST', + data: { + 'newName': name + }, + url: url + }); + } } }, /** @@ -179,6 +181,7 @@ define(function(require) { config.plugins.push('checkbox'); config.plugins.push('contextmenu'); config.plugins.push('dnd'); + config.plugins.push('unique'); config.checkbox = { whole_node: false, @@ -238,7 +241,15 @@ define(function(require) { "seperator_after": false, "label": "Folder", action: function (data) { - tree.create_node($node, { text: _.__('kiboko.dam.js.jstree.contextmenu.newfile.label'), type: 'default' }); + var inst = $.jstree.reference(data.reference), + obj = inst.get_node(data.reference); + inst.create_node(obj, {}, "last", function (new_node) { + try { + inst.edit(new_node); + } catch (ex) { + setTimeout(function () { inst.edit(new_node); },0); + } + }); tree.deselect_all(); tree.select_node($node); } From 1f301e38527753cfb98a0cb8fcc693f35a777518 Mon Sep 17 00:00:00 2001 From: julien Date: Mon, 24 Dec 2018 17:08:32 +0100 Subject: [PATCH 05/42] Document datagrid updated ( view and update link ) --- .../Controller/DocumentController.php | 79 +++++++++++++++ .../Resources/config/oro/datagrids.yml | 33 +++++++ .../Resources/views/Document/update.html.twig | 95 ++++++++++++------- .../Resources/views/Document/view.html.twig | 47 +++++++++ 4 files changed, 219 insertions(+), 35 deletions(-) create mode 100644 src/DAMBundle/Resources/views/Document/view.html.twig diff --git a/src/DAMBundle/Controller/DocumentController.php b/src/DAMBundle/Controller/DocumentController.php index d95416d..1fca74e 100644 --- a/src/DAMBundle/Controller/DocumentController.php +++ b/src/DAMBundle/Controller/DocumentController.php @@ -4,6 +4,7 @@ use Kiboko\Bundle\DAMBundle\Entity\Document; use Kiboko\Bundle\DAMBundle\Form\Handler\DocumentHandler; +use Kiboko\Bundle\DAMBundle\Form\Type\DocumentType; use Kiboko\Bundle\DAMBundle\Model\DocumentNodeInterface; use Oro\Bundle\SecurityBundle\Annotation\Acl; use Oro\Bundle\UIBundle\Route\Router; @@ -13,6 +14,7 @@ use Symfony\Bundle\FrameworkBundle\Controller\Controller; use Symfony\Component\Form\Form; use Symfony\Component\HttpFoundation\Request; +use Symfony\Component\HttpFoundation\Response; use Symfony\Component\HttpFoundation\Session\Session; use Symfony\Component\Translation\TranslatorInterface; @@ -133,4 +135,81 @@ private function updateWidget( ] ); } + + /** + * @param Document $document + * @return array|Response + * + * @Route("/{uuid}/view", + * name="kiboko_dam_document_view", + * requirements={"uuid"="[\da-f]{8}-[\da-f]{4}-[\da-f]{4}-[\da-f]{4}-[\da-f]{12}"} + * ) + * @ParamConverter("document", + * class="KibokoDAMBundle:Document", + * options={ + * "mapping": { + * "uuid": "uuid", + * }, + * "map_method_signature" = true, + * } + * ) + * @Acl( + * id="kiboko_dam_document_view", + * type="entity", + * class="KibokoDAMBundle:DocumentDocument", + * permission="VIEW" + * ) + * @Template() + */ + public function viewAction(Document $document) + { + return [ + 'entity' => $document, + ]; + } + + + /** + * @param Document $document + * @param Request $request + * @return array|Response + * + * @Route("/{uuid}/update", + * name="kiboko_dam_document_update", + * requirements={"uuid"="[\da-f]{8}-[\da-f]{4}-[\da-f]{4}-[\da-f]{4}-[\da-f]{12}"} + * ) + * @ParamConverter("document", + * class="KibokoDAMBundle:Document", + * options={ + * "mapping": { + * "uuid": "uuid", + * }, + * "map_method_signature" = true, + * } + * ) + * @Acl( + * id="kiboko_dam_document_view", + * type="entity", + * class="KibokoDAMBundle:DocumentDocument", + * permission="VIEW" + * ) + * @Template() + */ + public function updateAction(Document $document, Request $request) + { + return $this->update($document, $request); + } + + protected function update(Document $document, Request $request) + { + $form = $this->createForm(DocumentType::class, $document); + + return $this->get('oro_form.update_handler')->update( + $document, + $form, + $this->get('translator')->trans('kiboko.dam.views.document.update.save.label'), + $request, + null + ); + } } diff --git a/src/DAMBundle/Resources/config/oro/datagrids.yml b/src/DAMBundle/Resources/config/oro/datagrids.yml index 69cfd52..58117e8 100644 --- a/src/DAMBundle/Resources/config/oro/datagrids.yml +++ b/src/DAMBundle/Resources/config/oro/datagrids.yml @@ -122,6 +122,7 @@ datagrids: - file.id AS fileId - file.filename AS fileName - owner.username + - document.uuid AS uuid from: - { table: KibokoDAMBundle:Document, alias: document } join: @@ -145,6 +146,38 @@ datagrids: slug: type: localized_value data_name: slugs + view_link: + type: url + route: kiboko_dam_document_view + params: + - uuid + update_link: + type: url + route: kiboko_dam_document_update + params: + - uuid + actions: + view: + acl_resource: kiboko_dam_document_view + type: navigate + label: oro.grid.action.view + link: view_link + icon: eye + rowAction: true + update: + acl_resource: kiboko_project_update + type: navigate + label: oro.grid.action.update + link: update_link + icon: edit + rowAction: true + # delete: + # acl_resource: kiboko_api_delete_project + # type: delete + # label: oro.grid.action.delete + # link: delete_link + # icon: trash + # rowAction: true columns: name: label: kiboko.dam.document.datagrid.columns.name.label diff --git a/src/DAMBundle/Resources/views/Document/update.html.twig b/src/DAMBundle/Resources/views/Document/update.html.twig index a6ad01c..90d034f 100644 --- a/src/DAMBundle/Resources/views/Document/update.html.twig +++ b/src/DAMBundle/Resources/views/Document/update.html.twig @@ -1,37 +1,62 @@ -{% if saved is defined and saved %} - {% set messageText = update|default(false) ? 'kiboko.dam.views.document.update.update.label'|trans : 'kiboko.dam.views.document.update.created.label'|trans %} - {% set widgetResponse = { - widget: { - message: messageText|trans, - triggerSuccess: true, - remove: true - } +{% extends 'OroUIBundle:actions:update.html.twig' %} + +{% form_theme form with 'OroFormBundle:Form:fields.html.twig' %} + + +{% set document = form.vars.value %} + +{% set formAction = path('kiboko_dam_document_update', { 'uuid': document.uuid }) %} + + +{% block navButtons %} + + {{ UI.cancelButton(path('kiboko_dam_index')) }} + {% set html = UI.saveAndCloseButton({ + 'route': 'kiboko_dam_node_browse', + 'params': {'uuid': '$uuid'} + }) %} + + + {{ UI.dropdownSaveButton({'html': html}) }} + +{% endblock navButtons %} + +{% block pageHeader %} + {% if document.uuid %} + {% set breadcrumbs = { + 'entity': document, + 'indexPath': path('kiboko_dam_index'), + 'indexLabel': 'kiboko.dam.views.teamstorage.update.entity.label' | trans, + 'entityTitle': document.names|localized_value + } %} + {{ parent() }} + {% else %} + {% set title = 'oro.ui.create_entity'|trans({ '%entityName%': 'Document' }) %} + {{ include('OroUIBundle::page_title_block.html.twig', { title: title }) }} + {% endif %} +{% endblock pageHeader %} + +{% block content_data %} + {% set id = 'document-edit' %} + {% set dataBlocks = [ + { + 'title': 'kiboko.dam.views.document.update.general.label'|trans, + 'class': 'active', + 'subblocks': [{ + 'title': '', + 'data': [ + form_row(form.names), + form_row(form.slugs), + form_row(form.file), + ]} + ] + }, + ] %} + + {% set data = { + 'formErrors': form_errors(form) ? form_errors(form) : null, + 'dataBlocks': dataBlocks, } %} - {{ widgetResponse|json_encode|raw }} -{% else %} -
- {% form_theme form with ['OroFormBundle:Form:fields.html.twig', _self] %} - -
-
-
-
- {{ form_row(form.names) }} - {{ form_row(form.slugs) }} - {{ form_row(form.file) }} - {% if form.owner is defined %} - {{ form_row(form.owner) }} - {% endif %} - {{ form_rest(form) }} -
- -
-
- {{ oro_form_js_validation(form) }} -
-
-{% endif %} + {{ parent() }} +{% endblock content_data %} diff --git a/src/DAMBundle/Resources/views/Document/view.html.twig b/src/DAMBundle/Resources/views/Document/view.html.twig new file mode 100644 index 0000000..9fe7427 --- /dev/null +++ b/src/DAMBundle/Resources/views/Document/view.html.twig @@ -0,0 +1,47 @@ +{% extends 'OroUIBundle:actions:view.html.twig' %} +{% import 'OroUIBundle::macros.html.twig' as UI %} +{% import 'OroDataGridBundle::macros.html.twig' as dataGrid %} + +{% oro_title_set({params : {"%document.name%": entity.names|localized_value} }) %} + +{% block navButtons %} + {% if is_granted('EDIT', entity) %} + {{ UI.editButton({ + 'path' : path('kiboko_dam_document_update', { 'uuid': entity.uuid }), + 'entity_label': 'kiboko.dam.document.entity_label'|trans + }) }} + {% endif %} +{% endblock navButtons %} + +{% block pageHeader %} + {% set breadcrumbs = { + 'entity': entity, + 'indexPath': path('kiboko_dam_index'), + 'indexLabel': 'kiboko.dam.documentnode.entity_plural_label'|trans, + 'entityTitle': entity.names|localized_value + } %} + {{ parent() }} +{% endblock pageHeader %} + +{% block content_data %} + {% set info %} + {{ UI.renderProperty('kiboko.dam.document.datagrid.columns.owner.label'|trans, entity.owner.username) }} + {{ UI.renderProperty('kiboko.dam.document.datagrid.columns.name.label'|trans, entity.names|localized_value) }} + {{ UI.renderProperty('kiboko.dam.document.datagrid.columns.slug.label'|trans, entity.file.file) }} + {% endset %} + + {% set info = [ + { + 'title': 'kiboko.dam.document.entity_label'|trans, + 'class': 'active', + 'subblocks': + [ + { 'data': [ info ] }, + ] + }, + ] %} + + {% set id = 'editorialView' %} + {% set data = {'dataBlocks': info} %} + {{ parent() }} +{% endblock content_data %} From edb0f78615ad9e942202f76e88efc78f65f809f2 Mon Sep 17 00:00:00 2001 From: julien Date: Mon, 24 Dec 2018 17:10:24 +0100 Subject: [PATCH 06/42] Fix missing exposing route for widget action and removed console.log --- .../Controller/AssetWidgetController.php | 4 +- .../public/js/app/views/tree-manage-view.js | 48 ++++++------------- 2 files changed, 18 insertions(+), 34 deletions(-) diff --git a/src/DAMBundle/Controller/AssetWidgetController.php b/src/DAMBundle/Controller/AssetWidgetController.php index 7fa55c4..cdbe9f5 100644 --- a/src/DAMBundle/Controller/AssetWidgetController.php +++ b/src/DAMBundle/Controller/AssetWidgetController.php @@ -87,7 +87,9 @@ public function __construct( * @Route("/{uuid}", * name="kiboko_dam_upload_asset_widget", * requirements={"uuid"="[\da-f]{8}-[\da-f]{4}-[\da-f]{4}-[\da-f]{4}-[\da-f]{12}"}, - * + * options={ + * "expose"=true, + * }, * ) * * @ParamConverter("node", diff --git a/src/DAMBundle/Resources/public/js/app/views/tree-manage-view.js b/src/DAMBundle/Resources/public/js/app/views/tree-manage-view.js index 2256773..3e407c1 100644 --- a/src/DAMBundle/Resources/public/js/app/views/tree-manage-view.js +++ b/src/DAMBundle/Resources/public/js/app/views/tree-manage-view.js @@ -98,7 +98,6 @@ define(function(require) { onNodeNameChange: function(e, data) { var uuid = data.node.original.uuid; if (uuid) { - console.log(uuid); var name = data.text; if (data.node.original.uuid !== '') { var url = routing.generate('kiboko_dam_document_node_tree_ajax_rename', {uuid: uuid}); @@ -120,7 +119,6 @@ define(function(require) { * @param {Object} data */ onNodeCreate: function(e, data) { - console.log("YOP"); var parent = data.parent; var name = data.node.original.text; @@ -222,38 +220,22 @@ define(function(require) { this.edit($node); }).bind(tree) }, - "Create": { - "separator_before": false, - "separator_after": true, - "label": "Create", - "action": false, - "submenu": { - "File": { - "seperator_before": false, - "seperator_after": false, - "label": "File", - action: function (obj) { - //TO:DO upload widget - } - }, - "Folder": { - "seperator_before": false, - "seperator_after": false, - "label": "Folder", - action: function (data) { - var inst = $.jstree.reference(data.reference), - obj = inst.get_node(data.reference); - inst.create_node(obj, {}, "last", function (new_node) { - try { - inst.edit(new_node); - } catch (ex) { - setTimeout(function () { inst.edit(new_node); },0); - } - }); - tree.deselect_all(); - tree.select_node($node); + "Create Folder": { + "seperator_before": false, + "seperator_after": false, + "label": "Folder", + action: function (data) { + var inst = $.jstree.reference(data.reference), + obj = inst.get_node(data.reference); + inst.create_node(obj, {}, "last", function (new_node) { + try { + inst.edit(new_node); + } catch (ex) { + setTimeout(function () { inst.edit(new_node); },0); } - }, + }); + tree.deselect_all(); + tree.select_node($node); } }, "Remove": { From 375423181873e3c77fc4e82d409b9e673553f327 Mon Sep 17 00:00:00 2001 From: julien Date: Wed, 26 Dec 2018 09:51:20 +0100 Subject: [PATCH 07/42] Set every ajax request to asynchronous --- .../Resources/public/js/app/views/tree-manage-view.js | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/src/DAMBundle/Resources/public/js/app/views/tree-manage-view.js b/src/DAMBundle/Resources/public/js/app/views/tree-manage-view.js index 3e407c1..1ae47de 100644 --- a/src/DAMBundle/Resources/public/js/app/views/tree-manage-view.js +++ b/src/DAMBundle/Resources/public/js/app/views/tree-manage-view.js @@ -50,7 +50,7 @@ define(function(require) { var url = routing.generate('kiboko_dam_document_node_tree_ajax_delete', {uuid: uuid}); $.ajax({ - async: false, + async: true, type: 'DELETE', url: url }); @@ -81,7 +81,7 @@ define(function(require) { var uuid = data.node.original.uuid; var url = routing.generate('kiboko_dam_document_node_tree_ajax_move', {uuid: uuid}); $.ajax({ - async: false, + async: true, type: 'POST', data: { 'newParent': uuidParent @@ -102,7 +102,7 @@ define(function(require) { if (data.node.original.uuid !== '') { var url = routing.generate('kiboko_dam_document_node_tree_ajax_rename', {uuid: uuid}); $.ajax({ - async: false, + async: true, type: 'POST', data: { 'newName': name @@ -125,7 +125,7 @@ define(function(require) { if (data.node.original.uuid !== '') { var url = routing.generate('kiboko_dam_document_node_tree_ajax_create', {uuid: this.formatUuuid(parent)}); $.ajax({ - async: false, + async: true, type: 'POST', data: { 'name': name, From 6a7eac1ac11ccdf078738e589cf7853f79291bc1 Mon Sep 17 00:00:00 2001 From: julien Date: Wed, 26 Dec 2018 11:07:27 +0100 Subject: [PATCH 08/42] Updated traduction for contextMenu --- .../Resources/public/js/app/views/tree-manage-view.js | 2 +- src/DAMBundle/Resources/translations/jsmessages.en.yml | 2 +- src/DAMBundle/Resources/translations/jsmessages.fr_FR.yml | 4 ++-- 3 files changed, 4 insertions(+), 4 deletions(-) diff --git a/src/DAMBundle/Resources/public/js/app/views/tree-manage-view.js b/src/DAMBundle/Resources/public/js/app/views/tree-manage-view.js index 1ae47de..8bda983 100644 --- a/src/DAMBundle/Resources/public/js/app/views/tree-manage-view.js +++ b/src/DAMBundle/Resources/public/js/app/views/tree-manage-view.js @@ -223,7 +223,7 @@ define(function(require) { "Create Folder": { "seperator_before": false, "seperator_after": false, - "label": "Folder", + "label": _.__('kiboko.dam.js.jstree.contextmenu.newfolder.label'), action: function (data) { var inst = $.jstree.reference(data.reference), obj = inst.get_node(data.reference); diff --git a/src/DAMBundle/Resources/translations/jsmessages.en.yml b/src/DAMBundle/Resources/translations/jsmessages.en.yml index 3e4f0d4..54c0be5 100644 --- a/src/DAMBundle/Resources/translations/jsmessages.en.yml +++ b/src/DAMBundle/Resources/translations/jsmessages.en.yml @@ -7,5 +7,5 @@ kiboko: label: Rename delete: label: Delete - newfile: + newfolder: label: New folder \ No newline at end of file diff --git a/src/DAMBundle/Resources/translations/jsmessages.fr_FR.yml b/src/DAMBundle/Resources/translations/jsmessages.fr_FR.yml index ca2f67b..d4543d4 100644 --- a/src/DAMBundle/Resources/translations/jsmessages.fr_FR.yml +++ b/src/DAMBundle/Resources/translations/jsmessages.fr_FR.yml @@ -7,5 +7,5 @@ kiboko: label: Renommer delete: label: Supprimer - newfile: - label: Nouveau fichier \ No newline at end of file + newfolder: + label: Nouveau dossier \ No newline at end of file From 2b4009315f71d99cc854f1f00fc8a34a1dac2728 Mon Sep 17 00:00:00 2001 From: julien Date: Wed, 26 Dec 2018 11:10:32 +0100 Subject: [PATCH 09/42] Remove delete action from node controller --- .../Controller/DocumentNodeController.php | 29 ------------------- 1 file changed, 29 deletions(-) diff --git a/src/DAMBundle/Controller/DocumentNodeController.php b/src/DAMBundle/Controller/DocumentNodeController.php index 81df796..2378cdf 100644 --- a/src/DAMBundle/Controller/DocumentNodeController.php +++ b/src/DAMBundle/Controller/DocumentNodeController.php @@ -164,35 +164,6 @@ public function editAction(Request $request, DocumentNodeInterface $node) return $this->update($request, $node); } - /** - * @param Request $request - * - * @return array|Response - * - * @Route("/{uuid}/delete", - * name="kiboko_dam_node_delete", - * requirements={"uuid"="[\da-f]{8}-[\da-f]{4}-[\da-f]{4}-[\da-f]{4}-[\da-f]{12}"} - * ) - * @ParamConverter("parent", - * class="KibokoDAMBundle:DocumentNode", - * options={ - * "mapping": {"uuid": "uuid"}, - * "map_method_signature" = true, - * } - * ) - * @Acl( - * id="kiboko_dam_node_create", - * type="entity", - * class="KibokoDAMBundle:DocumentNode", - * permission="CREATE" - * ) - * @Template("KibokoDAMBundle:DocumentNode:update.html.twig") - */ - public function deleteAction(Request $request, DocumentNodeInterface $parent) - { - return new Response(null, 403); - } - /** * @param Request $request * @param DocumentNodeInterface $node From 4ec6c6f6b4c5f7edd3ef420b271401ceb65468ad Mon Sep 17 00:00:00 2001 From: julien Date: Wed, 26 Dec 2018 11:11:02 +0100 Subject: [PATCH 10/42] Add missing imports --- src/DAMBundle/Form/Handler/AssetHandler.php | 2 ++ 1 file changed, 2 insertions(+) diff --git a/src/DAMBundle/Form/Handler/AssetHandler.php b/src/DAMBundle/Form/Handler/AssetHandler.php index cc03ac6..4929de6 100644 --- a/src/DAMBundle/Form/Handler/AssetHandler.php +++ b/src/DAMBundle/Form/Handler/AssetHandler.php @@ -3,6 +3,8 @@ namespace Kiboko\Bundle\DAMBundle\Form\Handler; use Doctrine\ORM\EntityManager; +use Doctrine\ORM\OptimisticLockException; +use Doctrine\ORM\ORMException; use Kiboko\Bundle\DAMBundle\Entity\Document; use Kiboko\Bundle\DAMBundle\Model\Behavior\MovableInterface; use Kiboko\Bundle\DAMBundle\Model\DocumentInterface; From 0c2625ef433ee35e40848eb23aee5ff2c2d67d55 Mon Sep 17 00:00:00 2001 From: julien Date: Wed, 26 Dec 2018 11:11:50 +0100 Subject: [PATCH 11/42] Fixed move action for context menu --- .../DocumentNodeTreeAjaxController.php | 16 +++++++++++--- .../JsTree/DocumentNodeUpdateTreeHandler.php | 22 +++++++++++++++++++ .../public/js/app/views/tree-manage-view.js | 12 +++------- 3 files changed, 38 insertions(+), 12 deletions(-) diff --git a/src/DAMBundle/Controller/DocumentNodeTreeAjaxController.php b/src/DAMBundle/Controller/DocumentNodeTreeAjaxController.php index 8f79c3e..c660944 100644 --- a/src/DAMBundle/Controller/DocumentNodeTreeAjaxController.php +++ b/src/DAMBundle/Controller/DocumentNodeTreeAjaxController.php @@ -7,6 +7,7 @@ use Doctrine\ORM\ORMException; use Kiboko\Bundle\DAMBundle\Entity\DocumentNode; use Kiboko\Bundle\DAMBundle\JsTree\DocumentNodeUpdateTreeHandler; +use Kiboko\Bundle\DAMBundle\Model\Behavior\MovableInterface; use Kiboko\Bundle\DAMBundle\Model\DocumentNodeInterface; use Oro\Bundle\LocaleBundle\Helper\LocalizationHelper; use Sensio\Bundle\FrameworkExtraBundle\Configuration\Method; @@ -158,7 +159,7 @@ public function createNodeAction(Request $request, DocumentNodeInterface $node) } /** - * @Route("/move/{uuid}", + * @Route("/move/{uuid}/to/{uuidParent}", * name="kiboko_dam_document_node_tree_ajax_move", * requirements={"uuid"="[\da-f]{8}-[\da-f]{4}-[\da-f]{4}-[\da-f]{4}-[\da-f]{12}"}, * options={ @@ -174,13 +175,22 @@ public function createNodeAction(Request $request, DocumentNodeInterface $node) * "map_method_signature" = true, * } * ) + * @ParamConverter("newParent", + * class="KibokoDAMBundle:DocumentNode", + * options={ + * "mapping": { + * "uuidParent": "uuid", + * }, + * "map_method_signature" = true, + * } + * ) * @Method({"POST"}) * * {@inheritdoc} */ - public function moveAction(Request $request, DocumentNodeInterface $node) + public function moveAction(Request $request, MovableInterface $node,MovableInterface $newParent) { - $newparent= $request->get('newParent'); + return $this->handler->moveNode($node,$newParent); } diff --git a/src/DAMBundle/JsTree/DocumentNodeUpdateTreeHandler.php b/src/DAMBundle/JsTree/DocumentNodeUpdateTreeHandler.php index 879ebb6..4984cda 100644 --- a/src/DAMBundle/JsTree/DocumentNodeUpdateTreeHandler.php +++ b/src/DAMBundle/JsTree/DocumentNodeUpdateTreeHandler.php @@ -7,6 +7,7 @@ use Doctrine\ORM\ORMException; use Kiboko\Bundle\DAMBundle\Entity\DocumentNode; use Kiboko\Bundle\DAMBundle\Entity\TeamStorageNode; +use Kiboko\Bundle\DAMBundle\Model\Behavior\MovableInterface; use Kiboko\Bundle\DAMBundle\Model\DocumentNodeInterface; use Oro\Bundle\LocaleBundle\Entity\LocalizedFallbackValue; use Oro\Bundle\LocaleBundle\Helper\LocalizationHelper; @@ -213,4 +214,25 @@ public function createNode(DocumentNodeInterface $parent,string $name) { return new JsonResponse('created',200); } + + public function moveNode(MovableInterface $node, MovableInterface $newParent) + { + if (!$newParent instanceof DocumentNodeInterface || !$node instanceof DocumentNodeInterface) + { + return new JsonResponse('Arguments are not an instance of MovableInterface',500); + + } + $node->moveTo($newParent); + + try { + $this->entityManager->persist($node); + $this->entityManager->flush(); + } + catch (ORMException $e) { + return new JsonResponse($e->getMessage(),500); + } + + return new JsonResponse('moved folder successfully',200); + + } } diff --git a/src/DAMBundle/Resources/public/js/app/views/tree-manage-view.js b/src/DAMBundle/Resources/public/js/app/views/tree-manage-view.js index 8bda983..6fb5328 100644 --- a/src/DAMBundle/Resources/public/js/app/views/tree-manage-view.js +++ b/src/DAMBundle/Resources/public/js/app/views/tree-manage-view.js @@ -74,18 +74,12 @@ define(function(require) { */ onNodeMove: function(e, data) { - var newParent = data.parent; - var oldParent = data.old_parent; - var uuidParent = this.$tree.jstree(true).get_node(data.parent).original.uuid; - - var uuid = data.node.original.uuid; - var url = routing.generate('kiboko_dam_document_node_tree_ajax_move', {uuid: uuid}); + var uuid = this.formatUuuid(data.node.id); + var uuidParent = this.formatUuuid(data.parent); + var url = routing.generate('kiboko_dam_document_node_tree_ajax_move', {uuid: uuid,uuidParent: uuidParent}); $.ajax({ async: true, type: 'POST', - data: { - 'newParent': uuidParent - }, url: url }); }, From 93f56ff7944142c231c158f1893cbe8d9e69a8ad Mon Sep 17 00:00:00 2001 From: julien Date: Wed, 26 Dec 2018 15:41:36 +0100 Subject: [PATCH 12/42] Renamed entity tables names and created install for DAMBundle --- src/DAMBundle/Entity/Authorization.php | 2 +- src/DAMBundle/Entity/CDPStorage.php | 6 +- src/DAMBundle/Entity/Document.php | 10 +- src/DAMBundle/Entity/DocumentNode.php | 10 +- src/DAMBundle/Entity/LocalStorage.php | 4 +- src/DAMBundle/Entity/Meta.php | 2 +- .../Schema/KibokoDAMLogBundleInstaller.php | 596 ++++++++++++++++++ 7 files changed, 613 insertions(+), 17 deletions(-) create mode 100644 src/DAMBundle/Migrations/Schema/KibokoDAMLogBundleInstaller.php diff --git a/src/DAMBundle/Entity/Authorization.php b/src/DAMBundle/Entity/Authorization.php index 8f87c95..d93d16b 100644 --- a/src/DAMBundle/Entity/Authorization.php +++ b/src/DAMBundle/Entity/Authorization.php @@ -16,7 +16,7 @@ * "document" = "Kiboko\Bundle\DAMBundle\Entity\DocumentAuthorization", * "node" = "Kiboko\Bundle\DAMBundle\Entity\DocumentNodeAuthorization" * }) - * @ORM\Table(name="kiboko_dam_authorization") + * @ORM\Table(name="kbk_dam_authorization") */ abstract class Authorization implements AuthorizationInterface, IdentifiableInterface { diff --git a/src/DAMBundle/Entity/CDPStorage.php b/src/DAMBundle/Entity/CDPStorage.php index f536b3f..bdee177 100644 --- a/src/DAMBundle/Entity/CDPStorage.php +++ b/src/DAMBundle/Entity/CDPStorage.php @@ -15,7 +15,7 @@ class CDPStorage extends Transport /** * @var string * - * @ORM\Column(name="kiboko_dam_cdp_url", type="string", nullable=true) + * @ORM\Column(name="kbk_dam_cdp_url", type="string", nullable=true) * @Assert\NotBlank() * @Assert\Url() */ @@ -24,7 +24,7 @@ class CDPStorage extends Transport /** * @var int * - * @ORM\Column(name="kiboko_dam_cdp_client", type="string", nullable=true) + * @ORM\Column(name="kbk_dam_cdp_client", type="string", nullable=true) * @Assert\NotBlank() */ private $client; @@ -32,7 +32,7 @@ class CDPStorage extends Transport /** * @var int * - * @ORM\Column(name="kiboko_dam_cdp_secret", type="string", nullable=true) + * @ORM\Column(name="kbk_dam_cdp_secret", type="string", nullable=true) * @Assert\NotBlank() */ private $secret; diff --git a/src/DAMBundle/Entity/Document.php b/src/DAMBundle/Entity/Document.php index 2c615c6..723b548 100644 --- a/src/DAMBundle/Entity/Document.php +++ b/src/DAMBundle/Entity/Document.php @@ -30,7 +30,7 @@ /** * @ORM\Entity - * @ORM\Table(name="kiboko_dam_document") + * @ORM\Table(name="kbk_dam_document") * @ORM\HasLifecycleCallbacks() * @Config( * defaultValues={ @@ -113,7 +113,7 @@ class Document implements DocumentInterface, * fetch="EXTRA_LAZY", * ) * @ORM\JoinTable( - * name="kiboko_dam_document_name", + * name="kbk_dam_document_name", * joinColumns={ * @ORM\JoinColumn(name="document_id", referencedColumnName="id", onDelete="CASCADE") * }, @@ -140,7 +140,7 @@ class Document implements DocumentInterface, * fetch="EXTRA_LAZY", * ) * @ORM\JoinTable( - * name="kiboko_dam_document_slug", + * name="kbk_dam_document_slug", * joinColumns={ * @ORM\JoinColumn(name="document_id", referencedColumnName="id", onDelete="CASCADE") * }, @@ -167,7 +167,7 @@ class Document implements DocumentInterface, * fetch="EXTRA_LAZY", * ) * @ORM\JoinTable( - * name="kiboko_dam_document_metadata", + * name="kbk_dam_document_metadata", * joinColumns={ * @ORM\JoinColumn(name="document_id", referencedColumnName="id", onDelete="CASCADE") * }, @@ -195,7 +195,7 @@ class Document implements DocumentInterface, * fetch="EXTRA_LAZY", * ) * @ORM\JoinTable( - * name="kiboko_dam_document_authorization", + * name="kbk_dam_document_authorization", * joinColumns={ * @ORM\JoinColumn(name="document_id", referencedColumnName="id", onDelete="CASCADE") * }, diff --git a/src/DAMBundle/Entity/DocumentNode.php b/src/DAMBundle/Entity/DocumentNode.php index 7a57fd0..31838bc 100644 --- a/src/DAMBundle/Entity/DocumentNode.php +++ b/src/DAMBundle/Entity/DocumentNode.php @@ -30,7 +30,7 @@ /** * @ORM\Entity(repositoryClass="Kiboko\Bundle\DAMBundle\Repository\DocumentNodeRepository") - * @ORM\Table(name="kiboko_dam_node") + * @ORM\Table(name="kbk_dam_node") * @ORM\InheritanceType("SINGLE_TABLE") * @ORM\DiscriminatorColumn(name="type", type="string") * @Gedmo\Tree(type="nested") @@ -117,7 +117,7 @@ class DocumentNode implements DocumentNodeInterface, * fetch="EXTRA_LAZY", * ) * @ORM\JoinTable( - * name="kiboko_dam_node_name", + * name="kbk_dam_node_name", * joinColumns={ * @ORM\JoinColumn(name="document_id", referencedColumnName="id", onDelete="CASCADE") * }, @@ -144,7 +144,7 @@ class DocumentNode implements DocumentNodeInterface, * fetch="EXTRA_LAZY", * ) * @ORM\JoinTable( - * name="kiboko_dam_node_slug", + * name="kbk_dam_node_slug", * joinColumns={ * @ORM\JoinColumn(name="document_id", referencedColumnName="id", onDelete="CASCADE") * }, @@ -171,7 +171,7 @@ class DocumentNode implements DocumentNodeInterface, * fetch="EXTRA_LAZY", * ) * @ORM\JoinTable( - * name="kiboko_dam_node_metadata", + * name="kbk_dam_node_metadata", * joinColumns={ * @ORM\JoinColumn(name="document_id", referencedColumnName="id", onDelete="CASCADE") * }, @@ -199,7 +199,7 @@ class DocumentNode implements DocumentNodeInterface, * fetch="EXTRA_LAZY", * ) * @ORM\JoinTable( - * name="kiboko_dam_node_authorization", + * name="kbk_dam_node_authorization", * joinColumns={ * @ORM\JoinColumn(name="node_id", referencedColumnName="id", onDelete="CASCADE") * }, diff --git a/src/DAMBundle/Entity/LocalStorage.php b/src/DAMBundle/Entity/LocalStorage.php index 7f6f0ea..7dc4061 100644 --- a/src/DAMBundle/Entity/LocalStorage.php +++ b/src/DAMBundle/Entity/LocalStorage.php @@ -15,7 +15,7 @@ class LocalStorage extends Transport /** * @var string * - * @ORM\Column(name="kiboko_dam_path", type="string", nullable=true) + * @ORM\Column(name="kbk_dam_path", type="string", nullable=true) * @Assert\NotBlank() */ private $path; @@ -23,7 +23,7 @@ class LocalStorage extends Transport /** * @var int * - * @ORM\Column(name="kiboko_dam_local_lock", type="boolean", nullable=true) + * @ORM\Column(name="kbk_dam_local_lock", type="boolean", nullable=true) */ private $lock; diff --git a/src/DAMBundle/Entity/Meta.php b/src/DAMBundle/Entity/Meta.php index 351d54b..d427cf2 100644 --- a/src/DAMBundle/Entity/Meta.php +++ b/src/DAMBundle/Entity/Meta.php @@ -18,7 +18,7 @@ * "document" = "Kiboko\Bundle\DAMBundle\Entity\DocumentMeta", * "node" = "Kiboko\Bundle\DAMBundle\Entity\DocumentNodeMeta" * }) - * @ORM\Table(name="kiboko_dam_metadata") + * @ORM\Table(name="kbk_dam_metadata") */ abstract class Meta implements MetaInterface, IdentifiableInterface { diff --git a/src/DAMBundle/Migrations/Schema/KibokoDAMLogBundleInstaller.php b/src/DAMBundle/Migrations/Schema/KibokoDAMLogBundleInstaller.php new file mode 100644 index 0000000..00d6bf7 --- /dev/null +++ b/src/DAMBundle/Migrations/Schema/KibokoDAMLogBundleInstaller.php @@ -0,0 +1,596 @@ +alterOroIntegrationTransportTable($schema); + $this->createKibokoDamNodeSlugTable($schema); + $this->createKibokoDamNodeMetadataTable($schema); + $this->createKibokoDamNodeNameTable($schema); + $this->createKibokoDamDocumentNameTable($schema); + $this->createKibokoDamAuthorizationTable($schema); + $this->createKibokoDamDocumentSlugTable($schema); + $this->createKibokoDamNodeAuthorizationTable($schema); + $this->createKibokoDamNodeTable($schema); + $this->createKibokoDamDocumentAuthorizationTable($schema); + $this->createKibokoDamDocumentTable($schema); + $this->createKibokoDamMetadataTable($schema); + $this->createKibokoDamDocumentMetadataTable($schema); + + /** Foreign keys generation **/ + $this->addKibokoDamNodeSlugForeignKeys($schema); + $this->addKibokoDamNodeMetadataForeignKeys($schema); + $this->addKibokoDamNodeNameForeignKeys($schema); + $this->addKibokoDamDocumentNameForeignKeys($schema); + $this->addKibokoDamDocumentSlugForeignKeys($schema); + $this->addKibokoDamNodeAuthorizationForeignKeys($schema); + $this->addKibokoDamNodeForeignKeys($schema); + $this->addKibokoDamDocumentAuthorizationForeignKeys($schema); + $this->addKibokoDamDocumentForeignKeys($schema); + $this->addKibokoDamMetadataForeignKeys($schema); + $this->addKibokoDamDocumentMetadataForeignKeys($schema); + } + + /** + * Create oro_integration_transport table + * + * @param Schema $schema + * @throws \Doctrine\DBAL\Schema\SchemaException + */ + protected function alterOroIntegrationTransportTable(Schema $schema) + { + + if (!$schema->hasTable('oro_integration_transport')) { + return; + } + + $table = $schema->getTable('oro_integration_transport'); + $table->addColumn('kbk_dam_path', 'string', ['notnull' => false, 'length' => 255]); + $table->addColumn('kbk_dam_local_lock', 'boolean', ['notnull' => false]); + $table->addColumn('kbk_dam_cdp_url', 'string', ['notnull' => false, 'length' => 255]); + $table->addColumn('kbk_dam_cdp_client', 'string', ['notnull' => false, 'length' => 255]); + $table->addColumn('kbk_dam_cdp_secret', 'string', ['notnull' => false, 'length' => 255]); + } + + /** + * Create kbk_dam_node_slug table + * + * @param Schema $schema + */ + protected function createKibokoDamNodeSlugTable(Schema $schema) + { + $table = $schema->createTable('kbk_dam_node_slug'); + $table->addColumn('document_id', 'integer', []); + $table->addColumn('localized_value_id', 'integer', []); + $table->addUniqueIndex(['localized_value_id'], 'uniq_e375fb21eb576e89'); + $table->setPrimaryKey(['document_id', 'localized_value_id']); + $table->addIndex(['document_id'], 'idx_e375fb21c33f7837', []); + } + + /** + * Create kbk_dam_node_metadata table + * + * @param Schema $schema + */ + protected function createKibokoDamNodeMetadataTable(Schema $schema) + { + $table = $schema->createTable('kbk_dam_node_metadata'); + $table->addColumn('document_id', 'integer', []); + $table->addColumn('metadata_id', 'integer', []); + $table->addUniqueIndex(['metadata_id'], 'uniq_df12d9b7dc9ee959'); + $table->addIndex(['document_id'], 'idx_df12d9b7c33f7837', []); + $table->setPrimaryKey(['document_id', 'metadata_id']); + } + + /** + * Create kbk_dam_node_name table + * + * @param Schema $schema + */ + protected function createKibokoDamNodeNameTable(Schema $schema) + { + $table = $schema->createTable('kbk_dam_node_name'); + $table->addColumn('document_id', 'integer', []); + $table->addColumn('localized_value_id', 'integer', []); + $table->setPrimaryKey(['document_id', 'localized_value_id']); + $table->addUniqueIndex(['localized_value_id'], 'uniq_25cb1e45eb576e89'); + $table->addIndex(['document_id'], 'idx_25cb1e45c33f7837', []); + } + + /** + * Create kbk_dam_document_name table + * + * @param Schema $schema + */ + protected function createKibokoDamDocumentNameTable(Schema $schema) + { + $table = $schema->createTable('kbk_dam_document_name'); + $table->addColumn('document_id', 'integer', []); + $table->addColumn('localized_value_id', 'integer', []); + $table->setPrimaryKey(['document_id', 'localized_value_id']); + $table->addUniqueIndex(['localized_value_id'], 'uniq_d73c0763eb576e89'); + $table->addIndex(['document_id'], 'idx_d73c0763c33f7837', []); + } + + /** + * Create kbk_dam_authorization table + * + * @param Schema $schema + */ + protected function createKibokoDamAuthorizationTable(Schema $schema) + { + $table = $schema->createTable('kbk_dam_authorization'); + $table->addColumn('id', 'integer', ['autoincrement' => true]); + $table->addColumn('uuid', 'uuid', ['comment' => '(DC2Type:uuid)']); + $table->addColumn('authorizations', 'array', ['comment' => '(DC2Type:array)']); + $table->addColumn('type', 'string', ['length' => 255]); + $table->setPrimaryKey(['id']); + $table->addUniqueIndex(['uuid'], 'uniq_54c67e19d17f50a6'); + } + + /** + * Create kbk_dam_document_slug table + * + * @param Schema $schema + */ + protected function createKibokoDamDocumentSlugTable(Schema $schema) + { + $table = $schema->createTable('kbk_dam_document_slug'); + $table->addColumn('document_id', 'integer', []); + $table->addColumn('localized_value_id', 'integer', []); + $table->addUniqueIndex(['localized_value_id'], 'uniq_1182e207eb576e89'); + $table->addIndex(['document_id'], 'idx_1182e207c33f7837', []); + $table->setPrimaryKey(['document_id', 'localized_value_id']); + } + + /** + * Create kbk_dam_node_authorization table + * + * @param Schema $schema + */ + protected function createKibokoDamNodeAuthorizationTable(Schema $schema) + { + $table = $schema->createTable('kbk_dam_node_authorization'); + $table->addColumn('node_id', 'integer', []); + $table->addColumn('authorization_id', 'integer', []); + $table->addIndex(['node_id'], 'idx_1c3301e4460d9fd7', []); + $table->setPrimaryKey(['node_id', 'authorization_id']); + $table->addUniqueIndex(['authorization_id'], 'uniq_1c3301e42f8b0eb2'); + } + + /** + * Create kbk_dam_node table + * + * @param Schema $schema + */ + protected function createKibokoDamNodeTable(Schema $schema) + { + $table = $schema->createTable('kbk_dam_node'); + $table->addColumn('id', 'integer', ['autoincrement' => true]); + $table->addColumn('organization_id', 'integer', ['notnull' => false]); + $table->addColumn('updated_by_user_id', 'integer', ['notnull' => false]); + $table->addColumn('owner_user_id', 'integer', ['notnull' => false]); + $table->addColumn('root_id', 'integer', ['notnull' => false]); + $table->addColumn('parent_id', 'integer', ['notnull' => false]); + $table->addColumn('integration_id', 'integer', ['notnull' => false]); + $table->addColumn('thumbnail_id', 'integer', ['notnull' => false]); + $table->addColumn('uuid', 'uuid', ['comment' => '(DC2Type:uuid)']); + $table->addColumn('tree_left', 'integer', []); + $table->addColumn('tree_right', 'integer', []); + $table->addColumn('tree_level', 'integer', []); + $table->addColumn('created_at', 'datetime', ['comment' => '(DC2Type:datetime)']); + $table->addColumn('updated_at', 'datetime', ['comment' => '(DC2Type:datetime)']); + $table->addColumn('type', 'string', ['length' => 255]); + $table->addColumn('description', 'text', ['notnull' => false]); + $table->addIndex(['thumbnail_id'], 'idx_707b560efdff2e92', []); + $table->addIndex(['owner_user_id'], 'idx_707b560e2b18554a', []); + $table->addUniqueIndex(['uuid'], 'uniq_707b560ed17f50a6'); + $table->addIndex(['parent_id'], 'idx_707b560e727aca70', []); + $table->addIndex(['organization_id'], 'idx_707b560e32c8a3de', []); + $table->addIndex(['integration_id'], 'idx_707b560e9e82ddea', []); + $table->addIndex(['updated_by_user_id'], 'idx_707b560e2793cc5e', []); + $table->setPrimaryKey(['id']); + $table->addIndex(['root_id'], 'idx_707b560e79066886', []); + } + + /** + * Create kbk_dam_document_authorization table + * + * @param Schema $schema + */ + protected function createKibokoDamDocumentAuthorizationTable(Schema $schema) + { + $table = $schema->createTable('kbk_dam_document_authorization'); + $table->addColumn('document_id', 'integer', []); + $table->addColumn('authorization_id', 'integer', []); + $table->addIndex(['document_id'], 'idx_77af6c88c33f7837', []); + $table->addUniqueIndex(['authorization_id'], 'uniq_77af6c882f8b0eb2'); + $table->setPrimaryKey(['document_id', 'authorization_id']); + } + + /** + * Create kbk_dam_document table + * + * @param Schema $schema + */ + protected function createKibokoDamDocumentTable(Schema $schema) + { + $table = $schema->createTable('kbk_dam_document'); + $table->addColumn('id', 'integer', ['autoincrement' => true]); + $table->addColumn('organization_id', 'integer', ['notnull' => false]); + $table->addColumn('file_id', 'integer', ['notnull' => false]); + $table->addColumn('thumbnail_id', 'integer', ['notnull' => false]); + $table->addColumn('updated_by_user_id', 'integer', ['notnull' => false]); + $table->addColumn('owner_user_id', 'integer', ['notnull' => false]); + $table->addColumn('node_id', 'integer', ['notnull' => false]); + $table->addColumn('uuid', 'uuid', ['comment' => '(DC2Type:uuid)']); + $table->addColumn('created_at', 'datetime', ['comment' => '(DC2Type:datetime)']); + $table->addColumn('updated_at', 'datetime', ['comment' => '(DC2Type:datetime)']); + $table->addIndex(['owner_user_id'], 'idx_f20745c72b18554a', []); + $table->addIndex(['updated_by_user_id'], 'idx_f20745c72793cc5e', []); + $table->addUniqueIndex(['uuid'], 'uniq_f20745c7d17f50a6'); + $table->addIndex(['node_id'], 'idx_f20745c7460d9fd7', []); + $table->addIndex(['organization_id'], 'idx_f20745c732c8a3de', []); + $table->setPrimaryKey(['id']); + $table->addIndex(['file_id'], 'idx_f20745c793cb796c', []); + $table->addUniqueIndex(['thumbnail_id'], 'uniq_f20745c7fdff2e92'); + } + + /** + * Create kbk_dam_metadata table + * + * @param Schema $schema + */ + protected function createKibokoDamMetadataTable(Schema $schema) + { + $table = $schema->createTable('kbk_dam_metadata'); + $table->addColumn('id', 'integer', ['autoincrement' => true]); + $table->addColumn('localization_id', 'integer', ['notnull' => false]); + $table->addColumn('uuid', 'uuid', ['comment' => '(DC2Type:uuid)']); + $table->addColumn('raw', 'json', []); + $table->addColumn('type', 'string', ['length' => 255]); + $table->addIndex(['localization_id'], 'idx_657afba56a2856c7', []); + $table->addUniqueIndex(['uuid'], 'uniq_657afba5d17f50a6'); + $table->setPrimaryKey(['id']); + } + + /** + * Create kbk_dam_document_metadata table + * + * @param Schema $schema + */ + protected function createKibokoDamDocumentMetadataTable(Schema $schema) + { + $table = $schema->createTable('kbk_dam_document_metadata'); + $table->addColumn('document_id', 'integer', []); + $table->addColumn('metadata_id', 'integer', []); + $table->addIndex(['document_id'], 'idx_41f255e0c33f7837', []); + $table->setPrimaryKey(['document_id', 'metadata_id']); + $table->addUniqueIndex(['metadata_id'], 'uniq_41f255e0dc9ee959'); + } + + /** + * Add kbk_dam_node_slug foreign keys. + * + * @param Schema $schema + * @throws \Doctrine\DBAL\Schema\SchemaException + */ + protected function addKibokoDamNodeSlugForeignKeys(Schema $schema) + { + $table = $schema->getTable('kbk_dam_node_slug'); + $table->addForeignKeyConstraint( + $schema->getTable('kbk_dam_node'), + ['document_id'], + ['id'], + ['onUpdate' => null, 'onDelete' => 'CASCADE'] + ); + $table->addForeignKeyConstraint( + $schema->getTable('oro_fallback_localization_val'), + ['localized_value_id'], + ['id'], + ['onUpdate' => null, 'onDelete' => 'CASCADE'] + ); + } + + /** + * Add kbk_dam_node_metadata foreign keys. + * + * @param Schema $schema + * @throws \Doctrine\DBAL\Schema\SchemaException + */ + protected function addKibokoDamNodeMetadataForeignKeys(Schema $schema) + { + $table = $schema->getTable('kbk_dam_node_metadata'); + $table->addForeignKeyConstraint( + $schema->getTable('kbk_dam_node'), + ['document_id'], + ['id'], + ['onUpdate' => null, 'onDelete' => 'CASCADE'] + ); + $table->addForeignKeyConstraint( + $schema->getTable('kbk_dam_metadata'), + ['metadata_id'], + ['id'], + ['onUpdate' => null, 'onDelete' => 'CASCADE'] + ); + } + + /** + * Add kbk_dam_node_name foreign keys. + * + * @param Schema $schema + * @throws \Doctrine\DBAL\Schema\SchemaException + */ + protected function addKibokoDamNodeNameForeignKeys(Schema $schema) + { + $table = $schema->getTable('kbk_dam_node_name'); + $table->addForeignKeyConstraint( + $schema->getTable('kbk_dam_node'), + ['document_id'], + ['id'], + ['onUpdate' => null, 'onDelete' => 'CASCADE'] + ); + $table->addForeignKeyConstraint( + $schema->getTable('oro_fallback_localization_val'), + ['localized_value_id'], + ['id'], + ['onUpdate' => null, 'onDelete' => 'CASCADE'] + ); + } + + /** + * Add kbk_dam_document_name foreign keys. + * + * @param Schema $schema + * @throws \Doctrine\DBAL\Schema\SchemaException + */ + protected function addKibokoDamDocumentNameForeignKeys(Schema $schema) + { + $table = $schema->getTable('kbk_dam_document_name'); + $table->addForeignKeyConstraint( + $schema->getTable('kbk_dam_document'), + ['document_id'], + ['id'], + ['onUpdate' => null, 'onDelete' => 'CASCADE'] + ); + $table->addForeignKeyConstraint( + $schema->getTable('oro_fallback_localization_val'), + ['localized_value_id'], + ['id'], + ['onUpdate' => null, 'onDelete' => 'CASCADE'] + ); + } + + /** + * Add kbk_dam_document_slug foreign keys. + * + * @param Schema $schema + * @throws \Doctrine\DBAL\Schema\SchemaException + */ + protected function addKibokoDamDocumentSlugForeignKeys(Schema $schema) + { + $table = $schema->getTable('kbk_dam_document_slug'); + $table->addForeignKeyConstraint( + $schema->getTable('kbk_dam_document'), + ['document_id'], + ['id'], + ['onUpdate' => null, 'onDelete' => 'CASCADE'] + ); + $table->addForeignKeyConstraint( + $schema->getTable('oro_fallback_localization_val'), + ['localized_value_id'], + ['id'], + ['onUpdate' => null, 'onDelete' => 'CASCADE'] + ); + } + + /** + * Add kbk_dam_node_authorization foreign keys. + * + * @param Schema $schema + * @throws \Doctrine\DBAL\Schema\SchemaException + */ + protected function addKibokoDamNodeAuthorizationForeignKeys(Schema $schema) + { + $table = $schema->getTable('kbk_dam_node_authorization'); + $table->addForeignKeyConstraint( + $schema->getTable('kbk_dam_node'), + ['node_id'], + ['id'], + ['onUpdate' => null, 'onDelete' => 'CASCADE'] + ); + $table->addForeignKeyConstraint( + $schema->getTable('kbk_dam_authorization'), + ['authorization_id'], + ['id'], + ['onUpdate' => null, 'onDelete' => 'CASCADE'] + ); + } + + /** + * Add kbk_dam_node foreign keys. + * + * @param Schema $schema + * @throws \Doctrine\DBAL\Schema\SchemaException + */ + protected function addKibokoDamNodeForeignKeys(Schema $schema) + { + $table = $schema->getTable('kbk_dam_node'); + $table->addForeignKeyConstraint( + $schema->getTable('oro_organization'), + ['organization_id'], + ['id'], + ['onUpdate' => null, 'onDelete' => 'SET NULL'] + ); + $table->addForeignKeyConstraint( + $schema->getTable('oro_user'), + ['updated_by_user_id'], + ['id'], + ['onUpdate' => null, 'onDelete' => 'SET NULL'] + ); + $table->addForeignKeyConstraint( + $schema->getTable('oro_user'), + ['owner_user_id'], + ['id'], + ['onUpdate' => null, 'onDelete' => 'SET NULL'] + ); + $table->addForeignKeyConstraint( + $schema->getTable('kbk_dam_node'), + ['root_id'], + ['id'], + ['onUpdate' => null, 'onDelete' => 'CASCADE'] + ); + $table->addForeignKeyConstraint( + $schema->getTable('kbk_dam_node'), + ['parent_id'], + ['id'], + ['onUpdate' => null, 'onDelete' => 'CASCADE'] + ); + $table->addForeignKeyConstraint( + $schema->getTable('oro_integration_channel'), + ['integration_id'], + ['id'], + ['onUpdate' => null, 'onDelete' => 'CASCADE'] + ); + $table->addForeignKeyConstraint( + $schema->getTable('oro_attachment_file'), + ['thumbnail_id'], + ['id'], + ['onUpdate' => null, 'onDelete' => null] + ); + } + + /** + * Add kbk_dam_document_authorization foreign keys. + * + * @param Schema $schema + * @throws \Doctrine\DBAL\Schema\SchemaException + */ + protected function addKibokoDamDocumentAuthorizationForeignKeys(Schema $schema) + { + $table = $schema->getTable('kbk_dam_document_authorization'); + $table->addForeignKeyConstraint( + $schema->getTable('kbk_dam_document'), + ['document_id'], + ['id'], + ['onUpdate' => null, 'onDelete' => 'CASCADE'] + ); + $table->addForeignKeyConstraint( + $schema->getTable('kbk_dam_authorization'), + ['authorization_id'], + ['id'], + ['onUpdate' => null, 'onDelete' => 'CASCADE'] + ); + } + + /** + * Add kbk_dam_document foreign keys. + * + * @param Schema $schema + * @throws \Doctrine\DBAL\Schema\SchemaException + */ + protected function addKibokoDamDocumentForeignKeys(Schema $schema) + { + $table = $schema->getTable('kbk_dam_document'); + $table->addForeignKeyConstraint( + $schema->getTable('oro_organization'), + ['organization_id'], + ['id'], + ['onUpdate' => null, 'onDelete' => 'SET NULL'] + ); + $table->addForeignKeyConstraint( + $schema->getTable('oro_attachment_file'), + ['file_id'], + ['id'], + ['onUpdate' => null, 'onDelete' => null] + ); + $table->addForeignKeyConstraint( + $schema->getTable('oro_attachment_file'), + ['thumbnail_id'], + ['id'], + ['onUpdate' => null, 'onDelete' => null] + ); + $table->addForeignKeyConstraint( + $schema->getTable('oro_user'), + ['updated_by_user_id'], + ['id'], + ['onUpdate' => null, 'onDelete' => 'SET NULL'] + ); + $table->addForeignKeyConstraint( + $schema->getTable('oro_user'), + ['owner_user_id'], + ['id'], + ['onUpdate' => null, 'onDelete' => 'SET NULL'] + ); + $table->addForeignKeyConstraint( + $schema->getTable('kbk_dam_node'), + ['node_id'], + ['id'], + ['onUpdate' => null, 'onDelete' => 'CASCADE'] + ); + } + + /** + * Add kbk_dam_metadata foreign keys. + * + * @param Schema $schema + * @throws \Doctrine\DBAL\Schema\SchemaException + */ + protected function addKibokoDamMetadataForeignKeys(Schema $schema) + { + $table = $schema->getTable('kbk_dam_metadata'); + $table->addForeignKeyConstraint( + $schema->getTable('oro_localization'), + ['localization_id'], + ['id'], + ['onUpdate' => null, 'onDelete' => 'CASCADE'] + ); + } + + /** + * Add kbk_dam_document_metadata foreign keys. + * + * @param Schema $schema + * @throws \Doctrine\DBAL\Schema\SchemaException + */ + protected function addKibokoDamDocumentMetadataForeignKeys(Schema $schema) + { + $table = $schema->getTable('kbk_dam_document_metadata'); + $table->addForeignKeyConstraint( + $schema->getTable('kbk_dam_document'), + ['document_id'], + ['id'], + ['onUpdate' => null, 'onDelete' => 'CASCADE'] + ); + $table->addForeignKeyConstraint( + $schema->getTable('kbk_dam_metadata'), + ['metadata_id'], + ['id'], + ['onUpdate' => null, 'onDelete' => 'CASCADE'] + ); + } +} From cebb9a7cd46f00b8505986ca70a3444a47aa67f8 Mon Sep 17 00:00:00 2001 From: julien Date: Thu, 27 Dec 2018 14:29:21 +0100 Subject: [PATCH 13/42] browse at node view added --- .../Controller/DocumentNodeController.php | 52 ++++++ .../public/js/app/views/tree-manage-view.js | 77 ++++++--- .../views/DocumentNode/browse.html.twig | 1 - .../views/DocumentNode/browseToNode.html.twig | 149 ++++++++++++++++++ 4 files changed, 258 insertions(+), 21 deletions(-) create mode 100644 src/DAMBundle/Resources/views/DocumentNode/browseToNode.html.twig diff --git a/src/DAMBundle/Controller/DocumentNodeController.php b/src/DAMBundle/Controller/DocumentNodeController.php index 2378cdf..e49c036 100644 --- a/src/DAMBundle/Controller/DocumentNodeController.php +++ b/src/DAMBundle/Controller/DocumentNodeController.php @@ -100,6 +100,58 @@ public function browseAction(TeamStorageNode $node) 'tree' => $this->treeHandler->createTree($node), ]; } + /** + * @param TeamStorageNode $teamStorageNode + * @param DocumentNode $node + * @return array|Response + * + * @Route("/{uuid}/browse/{uuid2}", + * name="kiboko_dam_node_browse_to_node", + * requirements={"uuid"="[\da-f]{8}-[\da-f]{4}-[\da-f]{4}-[\da-f]{4}-[\da-f]{12}", + * "uuid2"="[\da-f]{8}-[\da-f]{4}-[\da-f]{4}-[\da-f]{4}-[\da-f]{12}"} + * ) + * @ParamConverter("teamstoragenode", + * class="KibokoDAMBundle:TeamStorageNode", + * options={ + * "mapping": { + * "uuid": "uuid", + * }, + * "map_method_signature" = true, + * } + * ) + * @ParamConverter("node", + * class="KibokoDAMBundle:DocumentNode", + * options={ + * "mapping": { + * "uuid2": "uuid", + * }, + * "map_method_signature" = true, + * } + * ) + * @Acl( + * id="kiboko_dam_node_view", + * type="entity", + * class="KibokoDAMBundle:DocumentNode", + * permission="VIEW" + * ) + * @Template() + */ + public function browseToNodeAction(TeamStorageNode $teamStorageNode, DocumentNode $node) + { + + $path = []; + $parent = $teamStorageNode; + while (($parent = $parent->getParent()) !== null) { + $path[] = $parent; + } + + return [ + 'teamstorage' => $teamStorageNode, + 'node' => $node, + 'path' => $path, + 'tree' => $this->treeHandler->createTree($teamStorageNode), + ]; + } /** * @param Request $request diff --git a/src/DAMBundle/Resources/public/js/app/views/tree-manage-view.js b/src/DAMBundle/Resources/public/js/app/views/tree-manage-view.js index 6fb5328..4f2c8c1 100644 --- a/src/DAMBundle/Resources/public/js/app/views/tree-manage-view.js +++ b/src/DAMBundle/Resources/public/js/app/views/tree-manage-view.js @@ -1,4 +1,4 @@ -define(function(require) { +define(function (require) { 'use strict'; var TreeManageView; @@ -18,7 +18,7 @@ define(function(require) { */ TreeManageView = BaseTreeManageView.extend({ - formatUuuid: function(chain) { + formatUuuid: function (chain) { return chain.substr(5).replace(/_/g, '-'); }, @@ -35,16 +35,29 @@ define(function(require) { 'delete_node.jstree': 'onNodeDelete', 'move_node.jstree': 'onNodeMove', 'select_node.jstree': 'onNodeOpen', + 'dnd_stop.vakata': 'onDragStop', }, + /** * Triggers after node deleted in tree * * @param {Event} e * @param {Object} data */ - onNodeDelete: function(e, data) { + onDragStop: function (e, data) { + + console.log('salut'); + + }, + /** + * Triggers after node deleted in tree + * + * @param {Event} e + * @param {Object} data + */ + onNodeDelete: function (e, data) { var uuid = data.node.original.uuid; var url = routing.generate('kiboko_dam_document_node_tree_ajax_delete', {uuid: uuid}); @@ -55,14 +68,21 @@ define(function(require) { url: url }); }, + reloadUrl: function () { + var url = window.location.pathname; + var regex = /browse(.*)/g; + var newUrl = 'browse/'; + newUrl += this.formatUuuid(data.node.id); + window.history.pushState("", "", url.replace(regex,newUrl)); + }, /** * Triggers after node is opened * * @param {Event} e * @param {Object} data */ - onNodeOpen: function(e, data) { - + onNodeOpen: function (e, data) { + this.reloadUrl(); mediator.trigger('datagrid:setParam:' + 'kiboko-dam-documents-grid', 'parent', this.formatUuuid(data.node.original.id)); mediator.trigger('datagrid:doRefresh:' + 'kiboko-dam-documents-grid'); }, @@ -72,16 +92,31 @@ define(function(require) { * @param {Event} e * @param {Object} data */ - onNodeMove: function(e, data) { + onNodeMove: function (e, data) { + if (data.node.parent === "#") { + e.stopImmediatePropagation(); + this.tree.jstree("refresh"); + return; + } var uuid = this.formatUuuid(data.node.id); var uuidParent = this.formatUuuid(data.parent); - var url = routing.generate('kiboko_dam_document_node_tree_ajax_move', {uuid: uuid,uuidParent: uuidParent}); - $.ajax({ - async: true, - type: 'POST', - url: url - }); + + if (uuid && uuidParent) { + + if (uuid !== uuidParent) { + var url = routing.generate('kiboko_dam_document_node_tree_ajax_move', { + uuid: uuid, + uuidParent: uuidParent + }); + $.ajax({ + async: true, + type: 'POST', + url: url + }); + } + } + }, /** * Triggers after node change name @@ -89,7 +124,7 @@ define(function(require) { * @param {Event} e * @param {Object} data */ - onNodeNameChange: function(e, data) { + onNodeNameChange: function (e, data) { var uuid = data.node.original.uuid; if (uuid) { var name = data.text; @@ -112,8 +147,8 @@ define(function(require) { * @param {Event} e * @param {Object} data */ - onNodeCreate: function(e, data) { - var parent = data.parent; + onNodeCreate: function (e, data) { + var parent = data.parent; var name = data.node.original.text; if (data.node.original.uuid !== '') { @@ -135,7 +170,7 @@ define(function(require) { * @param {Event} e * @param {Object} selected */ - onSelect: function(e, selected) { + onSelect: function (e, selected) { BaseTreeManageView.__super__.onSelect.apply(this, arguments); @@ -164,13 +199,13 @@ define(function(require) { * @param {Object} config * @returns {Object} */ - customizeTreeConfig: function(options, config) { + customizeTreeConfig: function (options, config) { config.root = { - "valid_children" : ["default"], + "valid_children": ["default"], } if (this.checkboxEnabled) { - config.plugins.push('checkbox'); + // config.plugins.push('checkbox'); config.plugins.push('contextmenu'); config.plugins.push('dnd'); config.plugins.push('unique'); @@ -225,7 +260,9 @@ define(function(require) { try { inst.edit(new_node); } catch (ex) { - setTimeout(function () { inst.edit(new_node); },0); + setTimeout(function () { + inst.edit(new_node); + }, 0); } }); tree.deselect_all(); diff --git a/src/DAMBundle/Resources/views/DocumentNode/browse.html.twig b/src/DAMBundle/Resources/views/DocumentNode/browse.html.twig index 3f1af74..f1f9d54 100644 --- a/src/DAMBundle/Resources/views/DocumentNode/browse.html.twig +++ b/src/DAMBundle/Resources/views/DocumentNode/browse.html.twig @@ -29,7 +29,6 @@ {% endblock pageHeader %} -
{{ UI.button({ 'path' : path(routePrefix ~ 'create', { uuid: entity.uuid }), diff --git a/src/DAMBundle/Resources/views/DocumentNode/browseToNode.html.twig b/src/DAMBundle/Resources/views/DocumentNode/browseToNode.html.twig new file mode 100644 index 0000000..e58a560 --- /dev/null +++ b/src/DAMBundle/Resources/views/DocumentNode/browseToNode.html.twig @@ -0,0 +1,149 @@ +{% extends bap.layout %} + +{% import 'OroUIBundle::macros.html.twig' as UI %} +{% import 'OroDataGridBundle::macros.html.twig' as dataGrid %} + +{% set reloadLink -%} + + {{- 'oro.navigation.menuupdate.reload_link.label'|trans -}} + +{%- endset %} + +{% block content %} + {% set routePrefix = 'kiboko_dam_node_' %} + + {% set breadcrumbs = { + 'entity': teamstorage, + 'indexPath': path('kiboko_dam_index'), + 'indexLabel': 'kiboko.dam.teamstoragenode.entity_plural_label'|trans, + 'entityTitle': teamstorage.names|localized_value + } %} + +
+
+ +
+ + + +
+{% endblock content %} From 0f4040e096c1d0902724d549a66ab59a64726912 Mon Sep 17 00:00:00 2001 From: julien Date: Fri, 28 Dec 2018 11:19:30 +0100 Subject: [PATCH 14/42] Node openening when refreshing working. Node selecting when refreshing working. Upload asset data-url updating when refreshing. --- .../public/js/app/views/tree-manage-view.js | 33 ++++++++++++++----- .../views/DocumentNode/browseToNode.html.twig | 2 +- 2 files changed, 25 insertions(+), 10 deletions(-) diff --git a/src/DAMBundle/Resources/public/js/app/views/tree-manage-view.js b/src/DAMBundle/Resources/public/js/app/views/tree-manage-view.js index 4f2c8c1..6ba1720 100644 --- a/src/DAMBundle/Resources/public/js/app/views/tree-manage-view.js +++ b/src/DAMBundle/Resources/public/js/app/views/tree-manage-view.js @@ -36,9 +36,27 @@ define(function (require) { 'move_node.jstree': 'onNodeMove', 'select_node.jstree': 'onNodeOpen', 'dnd_stop.vakata': 'onDragStop', - + 'ready.jstree': 'onTreeLoaded', }, + onTreeLoaded: function (e,data) { + var url = window.location.pathname; + var regex = /(?<=browse\/).*$/g; + var nodeUuid = url.match(regex).toString(); + console.log(dataUrl); + var str = 'node_'; + + if(nodeUuid) { + + var dataUrl = $(".upload_button_widget").attr('data-url'); + $(".upload_button_widget").attr('data-url',dataUrl.replace(/\b[0-9a-f]{8}\b-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{4}-\b[0-9a-f]{12}\b/ + ,nodeUuid )); + nodeUuid = nodeUuid.replace(/-/g, '_'); + nodeUuid = str.concat('', nodeUuid); + this.jsTreeInstance._open_to(nodeUuid); + this.jsTreeInstance.select_node(nodeUuid); + } + }, /** * Triggers after node deleted in tree @@ -68,13 +86,6 @@ define(function (require) { url: url }); }, - reloadUrl: function () { - var url = window.location.pathname; - var regex = /browse(.*)/g; - var newUrl = 'browse/'; - newUrl += this.formatUuuid(data.node.id); - window.history.pushState("", "", url.replace(regex,newUrl)); - }, /** * Triggers after node is opened * @@ -82,7 +93,11 @@ define(function (require) { * @param {Object} data */ onNodeOpen: function (e, data) { - this.reloadUrl(); + var url = window.location.pathname; + var regex = /browse(.*)/g; + var newUrl = 'browse/'; + newUrl += this.formatUuuid(data.node.id); + window.history.pushState("", "", url.replace(regex,newUrl)); mediator.trigger('datagrid:setParam:' + 'kiboko-dam-documents-grid', 'parent', this.formatUuuid(data.node.original.id)); mediator.trigger('datagrid:doRefresh:' + 'kiboko-dam-documents-grid'); }, diff --git a/src/DAMBundle/Resources/views/DocumentNode/browseToNode.html.twig b/src/DAMBundle/Resources/views/DocumentNode/browseToNode.html.twig index e58a560..62525ae 100644 --- a/src/DAMBundle/Resources/views/DocumentNode/browseToNode.html.twig +++ b/src/DAMBundle/Resources/views/DocumentNode/browseToNode.html.twig @@ -43,7 +43,7 @@ {# Create Divider button #} {% set html = UI.clientButton({ 'dataUrl': path('kiboko_dam_upload_asset_widget', { uuid: teamstorage.uuid}), - 'aCss': 'btn-primary', + 'aCss': 'btn-primary upload_button_widget', 'iCss': 'fa-image', 'label': 'kiboko.dam.updload'|trans({ '%entityName%': 'kiboko.dam.document.entity_label'|trans }), 'widget': { From d3bb796fc53c935e0ffb69f7348ce68f46783927 Mon Sep 17 00:00:00 2001 From: julien Date: Fri, 28 Dec 2018 11:31:34 +0100 Subject: [PATCH 15/42] Little refractor for some warnings --- .../Controller/TeamStorageNodeController.php | 7 +++---- .../DependencyInjection/KibokoDAMExtension.php | 5 +++++ src/DAMBundle/Entity/Authorization.php | 16 ++++++++++++++++ src/DAMBundle/Entity/Document.php | 2 +- 4 files changed, 25 insertions(+), 5 deletions(-) diff --git a/src/DAMBundle/Controller/TeamStorageNodeController.php b/src/DAMBundle/Controller/TeamStorageNodeController.php index ede19ee..b4dcbcb 100644 --- a/src/DAMBundle/Controller/TeamStorageNodeController.php +++ b/src/DAMBundle/Controller/TeamStorageNodeController.php @@ -38,10 +38,9 @@ final class TeamStorageNodeController extends Controller /** - * @param Form $form - * @param UpdateHandlerFacade $handler - * @param TranslatorInterface $translator - * @param DocumentNodeUpdateTreeHandler $treeHandler + * @param Form $form + * @param UpdateHandlerFacade $handler + * @param TranslatorInterface $translator */ public function __construct( Form $form, diff --git a/src/DAMBundle/DependencyInjection/KibokoDAMExtension.php b/src/DAMBundle/DependencyInjection/KibokoDAMExtension.php index b9dfcb2..cbce2f2 100644 --- a/src/DAMBundle/DependencyInjection/KibokoDAMExtension.php +++ b/src/DAMBundle/DependencyInjection/KibokoDAMExtension.php @@ -9,6 +9,11 @@ class KibokoDAMExtension extends Extension { + /** + * @param array $configs + * @param ContainerBuilder $container + * @throws \Exception + */ public function load(array $configs, ContainerBuilder $container) { $loader = new Loader\YamlFileLoader($container, new FileLocator(__DIR__ . '/../Resources/config')); diff --git a/src/DAMBundle/Entity/Authorization.php b/src/DAMBundle/Entity/Authorization.php index d93d16b..a52b107 100644 --- a/src/DAMBundle/Entity/Authorization.php +++ b/src/DAMBundle/Entity/Authorization.php @@ -81,4 +81,20 @@ public function getUuid(): UuidInterface { return $this->uuid; } + + /** + * @return DocumentActionInterface[] + */ + public function getAuthorizations() + { + return $this->authorizations; + } + + /** + * @param DocumentActionInterface[] $authorizations + */ + public function setAuthorizations(array $authorizations) + { + $this->authorizations = $authorizations; + } } diff --git a/src/DAMBundle/Entity/Document.php b/src/DAMBundle/Entity/Document.php index 723b548..521b8f5 100644 --- a/src/DAMBundle/Entity/Document.php +++ b/src/DAMBundle/Entity/Document.php @@ -450,7 +450,7 @@ public function setNode(DocumentNodeInterface $node): void public function getMimeType(): string { - $this->file->getMimeType(); + return $this->file->getMimeType(); } public function setFile(File $file): void From cfff77f11ef8b6a6bc902b2fa772bc62db025468 Mon Sep 17 00:00:00 2001 From: julien Date: Fri, 28 Dec 2018 15:05:29 +0100 Subject: [PATCH 16/42] Changed paramaters name for document node broswe view. Refractored js tree component. --- .../Controller/DocumentNodeController.php | 4 +- .../public/js/app/views/tree-manage-view.js | 51 +++--- .../views/DocumentNode/browse.html.twig | 24 +-- .../views/DocumentNode/browseToNode.html.twig | 149 ------------------ 4 files changed, 44 insertions(+), 184 deletions(-) delete mode 100644 src/DAMBundle/Resources/views/DocumentNode/browseToNode.html.twig diff --git a/src/DAMBundle/Controller/DocumentNodeController.php b/src/DAMBundle/Controller/DocumentNodeController.php index e49c036..d64b2ac 100644 --- a/src/DAMBundle/Controller/DocumentNodeController.php +++ b/src/DAMBundle/Controller/DocumentNodeController.php @@ -95,7 +95,7 @@ public function browseAction(TeamStorageNode $node) } return [ - 'entity' => $node, + 'teamstorage' => $node, 'path' => $path, 'tree' => $this->treeHandler->createTree($node), ]; @@ -134,7 +134,7 @@ public function browseAction(TeamStorageNode $node) * class="KibokoDAMBundle:DocumentNode", * permission="VIEW" * ) - * @Template() + * @Template("@KibokoDAM/DocumentNode/browse.html.twig") */ public function browseToNodeAction(TeamStorageNode $teamStorageNode, DocumentNode $node) { diff --git a/src/DAMBundle/Resources/public/js/app/views/tree-manage-view.js b/src/DAMBundle/Resources/public/js/app/views/tree-manage-view.js index 6ba1720..e2db2b0 100644 --- a/src/DAMBundle/Resources/public/js/app/views/tree-manage-view.js +++ b/src/DAMBundle/Resources/public/js/app/views/tree-manage-view.js @@ -18,8 +18,14 @@ define(function (require) { */ TreeManageView = BaseTreeManageView.extend({ - formatUuuid: function (chain) { - return chain.substr(5).replace(/_/g, '-'); + treeEvents: { + 'create_node.jstree': 'onNodeCreate', + 'rename_node.jstree': 'onNodeNameChange', + 'delete_node.jstree': 'onNodeDelete', + 'move_node.jstree': 'onNodeMove', + 'select_node.jstree': 'onNodeOpen', + 'dnd_stop.vakata': 'onDragStop', + 'ready.jstree': 'onTreeLoaded', }, /** @@ -29,29 +35,33 @@ define(function (require) { TreeManageView.__super__.constructor.apply(this, arguments); }, - treeEvents: { - 'create_node.jstree': 'onNodeCreate', - 'rename_node.jstree': 'onNodeNameChange', - 'delete_node.jstree': 'onNodeDelete', - 'move_node.jstree': 'onNodeMove', - 'select_node.jstree': 'onNodeOpen', - 'dnd_stop.vakata': 'onDragStop', - 'ready.jstree': 'onTreeLoaded', + formatUuuid: function (chain) { + return chain.substr(5).replace(/_/g, '-'); }, - onTreeLoaded: function (e,data) { + onTreeLoaded: function (e, data) { var url = window.location.pathname; var regex = /(?<=browse\/).*$/g; - var nodeUuid = url.match(regex).toString(); - console.log(dataUrl); - var str = 'node_'; + if(url.match(regex)) { + url = url.match(regex); + var nodeUuid = url.toString(); + var buttonUuid = nodeUuid; - if(nodeUuid) { + } + + if (nodeUuid) { + + $("div[class='grid-views']").ready(function(){ + mediator.trigger('datagrid:setParam:' + 'kiboko-dam-documents-grid', 'parent', buttonUuid); + mediator.trigger('datagrid:doRefresh:' + 'kiboko-dam-documents-grid'); + }); - var dataUrl = $(".upload_button_widget").attr('data-url'); - $(".upload_button_widget").attr('data-url',dataUrl.replace(/\b[0-9a-f]{8}\b-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{4}-\b[0-9a-f]{12}\b/ - ,nodeUuid )); - nodeUuid = nodeUuid.replace(/-/g, '_'); + var str = 'node_'; + var uploadWidget = $(".upload_button_widget"); + var dataUrl = uploadWidget.attr('data-url'); + var regexUuid = /\b[0-9a-f]{8}\b-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{4}-\b[0-9a-f]{12}\b/; + uploadWidget.attr('data-url', dataUrl.replace(regexUuid, nodeUuid)); + nodeUuid = nodeUuid.replace(/-/g, '_'); nodeUuid = str.concat('', nodeUuid); this.jsTreeInstance._open_to(nodeUuid); this.jsTreeInstance.select_node(nodeUuid); @@ -66,8 +76,6 @@ define(function (require) { */ onDragStop: function (e, data) { - console.log('salut'); - }, /** * Triggers after node deleted in tree @@ -98,6 +106,7 @@ define(function (require) { var newUrl = 'browse/'; newUrl += this.formatUuuid(data.node.id); window.history.pushState("", "", url.replace(regex,newUrl)); + mediator.trigger('datagrid:setParam:' + 'kiboko-dam-documents-grid', 'parent', this.formatUuuid(data.node.original.id)); mediator.trigger('datagrid:doRefresh:' + 'kiboko-dam-documents-grid'); }, diff --git a/src/DAMBundle/Resources/views/DocumentNode/browse.html.twig b/src/DAMBundle/Resources/views/DocumentNode/browse.html.twig index f1f9d54..a70671f 100644 --- a/src/DAMBundle/Resources/views/DocumentNode/browse.html.twig +++ b/src/DAMBundle/Resources/views/DocumentNode/browse.html.twig @@ -13,10 +13,10 @@ {% set routePrefix = 'kiboko_dam_node_' %} {% set breadcrumbs = { - 'entity': entity, + 'entity': teamstorage, 'indexPath': path('kiboko_dam_index'), 'indexLabel': 'kiboko.dam.teamstoragenode.entity_plural_label'|trans, - 'entityTitle': entity.names|localized_value + 'entityTitle': teamstorage.names|localized_value } %}
@@ -31,7 +31,7 @@
{{ UI.button({ - 'path' : path(routePrefix ~ 'create', { uuid: entity.uuid }), + 'path' : path(routePrefix ~ 'create', { uuid: teamstorage.uuid }), 'iCss': 'fa-folder', 'label': 'kiboko.dam.documentnode.create_label'|trans({ '%entityName%': 'kiboko.dam.documentnode.entity_label'|trans }), 'title': 'kiboko.dam.documentnode.create_label'|trans({ '%entityName%': 'kiboko.dam.documentnode.entity_label'|trans }) @@ -41,8 +41,8 @@ {# Create Divider button #} {% set html = UI.clientButton({ - 'dataUrl': path('kiboko_dam_upload_asset_widget', { uuid: entity.uuid}), - 'aCss': 'btn-primary', + 'dataUrl': path('kiboko_dam_upload_asset_widget', { uuid: teamstorage.uuid}), + 'aCss': 'btn-primary upload_button_widget', 'iCss': 'fa-image', 'label': 'kiboko.dam.updload'|trans({ '%entityName%': 'kiboko.dam.document.entity_label'|trans }), 'widget': { @@ -71,7 +71,7 @@ 'iCss': 'fa-plus', 'dataMethod': 'POST', 'dataRedirect': app.request.uri, - 'dataUrl': path(routePrefix ~ 'create', { uuid: entity.uuid, parentKey: entity.names|localized_value, 'isDivider': true }), + 'dataUrl': path(routePrefix ~ 'create', { uuid: teamstorage.uuid, parentKey: teamstorage.names|localized_value, 'isDivider': true }), 'successMessage': dividerCreatedMessage|default('kiboko.dam.documentnode.divider_created')|trans({'%reload_link%': reloadLink}) }) %} @@ -97,8 +97,8 @@ {% block content_data %} {% set treeOptions = { 'data' : tree, - 'menu' : entity.uuid, - 'nodeId': entity.uuid, + 'menu' : teamstorage.uuid, + 'nodeId': teamstorage.uuid, 'updateAllowed' : true, 'view' : 'kibokodam/js/app/views/tree-manage-view', 'onRootSelectRoute' : routePrefix ~ 'view', @@ -113,21 +113,21 @@ {% block sidebar %} {{ UI.renderJsTree( { - 'label': entity.names|localized_value, + 'label': teamstorage.names|localized_value, 'treeOptions': treeOptions }, { 'move': { 'view': 'oroui/js/app/views/jstree/move-action-view', 'routeName': routePrefix ~ 'move', - 'routeParams': {menuName: entity.uuid} + 'routeParams': {menuName: teamstorage.uuid} } } ) }} {% endblock sidebar %} {% block content %} - {% if entity.documents.empty %} + {% if teamstorage.documents.empty %}
{{ 'kiboko.dam.documentnode.empty_node'|trans }} @@ -136,7 +136,7 @@ {% else %}
- {{ dataGrid.renderGrid('kiboko-dam-documents-grid', { parent: entity.uuid }) }} + {{ dataGrid.renderGrid('kiboko-dam-documents-grid', { parent: teamstorage.uuid }) }}
{% endif %} diff --git a/src/DAMBundle/Resources/views/DocumentNode/browseToNode.html.twig b/src/DAMBundle/Resources/views/DocumentNode/browseToNode.html.twig deleted file mode 100644 index 62525ae..0000000 --- a/src/DAMBundle/Resources/views/DocumentNode/browseToNode.html.twig +++ /dev/null @@ -1,149 +0,0 @@ -{% extends bap.layout %} - -{% import 'OroUIBundle::macros.html.twig' as UI %} -{% import 'OroDataGridBundle::macros.html.twig' as dataGrid %} - -{% set reloadLink -%} - - {{- 'oro.navigation.menuupdate.reload_link.label'|trans -}} - -{%- endset %} - -{% block content %} - {% set routePrefix = 'kiboko_dam_node_' %} - - {% set breadcrumbs = { - 'entity': teamstorage, - 'indexPath': path('kiboko_dam_index'), - 'indexLabel': 'kiboko.dam.teamstoragenode.entity_plural_label'|trans, - 'entityTitle': teamstorage.names|localized_value - } %} - -
-
- -
- - - -
-{% endblock content %} From 5e1e5aaec5ffc1581b1962c93b936e49c1450b63 Mon Sep 17 00:00:00 2001 From: julien Date: Fri, 28 Dec 2018 16:18:21 +0100 Subject: [PATCH 17/42] prevent moving a child above or below the root --- .../Resources/public/js/app/views/tree-manage-view.js | 10 ++++++++++ 1 file changed, 10 insertions(+) diff --git a/src/DAMBundle/Resources/public/js/app/views/tree-manage-view.js b/src/DAMBundle/Resources/public/js/app/views/tree-manage-view.js index e2db2b0..eb432c6 100644 --- a/src/DAMBundle/Resources/public/js/app/views/tree-manage-view.js +++ b/src/DAMBundle/Resources/public/js/app/views/tree-manage-view.js @@ -225,6 +225,14 @@ define(function (require) { */ customizeTreeConfig: function (options, config) { + config.core.check_callback = function (operation, node, parent, position, more) { + if(operation === "copy_node" || operation === "move_node") { + if(parent.id === "#") { + return false; // prevent moving a child above or below the root + } + } + return true; // allow everything else + } config.root = { "valid_children": ["default"], } @@ -233,6 +241,8 @@ define(function (require) { config.plugins.push('contextmenu'); config.plugins.push('dnd'); config.plugins.push('unique'); + config.plugins.push('sort'); + config.plugins.push('state'); config.checkbox = { whole_node: false, From 31cc6d80cc19b8edf7c2328af73128dd1e6834a9 Mon Sep 17 00:00:00 2001 From: julien Date: Wed, 2 Jan 2019 10:41:14 +0100 Subject: [PATCH 18/42] [WIP] - Rest api for deleting documents - drag-and-drop --- .../Api/Rest/DocumentController.php | 47 +++++++++++ .../Api/Rest/DocumentNodeController.php | 44 ++++++++++ .../Resources/config/oro/datagrids.yml | 21 +++-- .../Resources/config/oro/routing.yml | 10 +++ src/DAMBundle/Resources/config/requirejs.yml | 1 + src/DAMBundle/Resources/config/services.yml | 7 ++ .../public/js/app/views/drag-and-drop.js | 83 +++++++++++++++++++ .../views/DocumentNode/browse.html.twig | 4 +- 8 files changed, 208 insertions(+), 9 deletions(-) create mode 100644 src/DAMBundle/Controller/Api/Rest/DocumentController.php create mode 100644 src/DAMBundle/Controller/Api/Rest/DocumentNodeController.php create mode 100644 src/DAMBundle/Resources/public/js/app/views/drag-and-drop.js diff --git a/src/DAMBundle/Controller/Api/Rest/DocumentController.php b/src/DAMBundle/Controller/Api/Rest/DocumentController.php new file mode 100644 index 0000000..0270ac2 --- /dev/null +++ b/src/DAMBundle/Controller/Api/Rest/DocumentController.php @@ -0,0 +1,47 @@ +handleDeleteRequest($document->getId()); + } + + public function getForm() + { + // This method is not needed to delete entities. + // + // Note: You will need to provide a proper implementation here + // when you start working with more features of REST APIs. + } + + public function getFormHandler() + { + // This method is not needed to delete entities. + // + // Note: You will need to provide a proper implementation here + // when you start working with more features of REST APIs. + } + + public function getManager() + { + return $this->get('kiboko_dam.document_manager.api'); + } +} \ No newline at end of file diff --git a/src/DAMBundle/Controller/Api/Rest/DocumentNodeController.php b/src/DAMBundle/Controller/Api/Rest/DocumentNodeController.php new file mode 100644 index 0000000..62160bc --- /dev/null +++ b/src/DAMBundle/Controller/Api/Rest/DocumentNodeController.php @@ -0,0 +1,44 @@ +handleDeleteRequest($id); + } + + public function getForm() + { + // This method is not needed to delete entities. + // + // Note: You will need to provide a proper implementation here + // when you start working with more features of REST APIs. + } + + public function getFormHandler() + { + // This method is not needed to delete entities. + // + // Note: You will need to provide a proper implementation here + // when you start working with more features of REST APIs. + } + + public function getManager() + { + return $this->get('kiboko.document_node_manager.api'); + } +} \ No newline at end of file diff --git a/src/DAMBundle/Resources/config/oro/datagrids.yml b/src/DAMBundle/Resources/config/oro/datagrids.yml index 58117e8..4948f42 100644 --- a/src/DAMBundle/Resources/config/oro/datagrids.yml +++ b/src/DAMBundle/Resources/config/oro/datagrids.yml @@ -122,6 +122,7 @@ datagrids: - file.id AS fileId - file.filename AS fileName - owner.username + - document.id AS id - document.uuid AS uuid from: - { table: KibokoDAMBundle:Document, alias: document } @@ -140,6 +141,7 @@ datagrids: default: null type: string properties: + id: ~ name: type: localized_value data_name: names @@ -156,6 +158,11 @@ datagrids: route: kiboko_dam_document_update params: - uuid +# delete_link: +# type: url +# route: kiboko_api_delete_document +# params: +# - id actions: view: acl_resource: kiboko_dam_document_view @@ -171,13 +178,13 @@ datagrids: link: update_link icon: edit rowAction: true - # delete: - # acl_resource: kiboko_api_delete_project - # type: delete - # label: oro.grid.action.delete - # link: delete_link - # icon: trash - # rowAction: true + delete: + acl_resource: kiboko_api_delete_document + type: delete + label: oro.grid.action.delete + link: delete_link + icon: trash + rowAction: true columns: name: label: kiboko.dam.document.datagrid.columns.name.label diff --git a/src/DAMBundle/Resources/config/oro/routing.yml b/src/DAMBundle/Resources/config/oro/routing.yml index b4bcaec..8611c9d 100644 --- a/src/DAMBundle/Resources/config/oro/routing.yml +++ b/src/DAMBundle/Resources/config/oro/routing.yml @@ -2,3 +2,13 @@ kiboko_dam_bundle: resource: "@KibokoDAMBundle/Controller" type: annotation prefix: /dam + +kiboko_dam.api.document: + resource: '@KibokoDAMBundle/Controller/Api/Rest/DocumentController.php' + type: rest + prefix: api/rest/{version}/ + requirements: + version: latest|v1 + _format: json + defaults: + version: latest \ No newline at end of file diff --git a/src/DAMBundle/Resources/config/requirejs.yml b/src/DAMBundle/Resources/config/requirejs.yml index f7551da..4058837 100644 --- a/src/DAMBundle/Resources/config/requirejs.yml +++ b/src/DAMBundle/Resources/config/requirejs.yml @@ -1,3 +1,4 @@ config: paths: 'kibokodam/js/app/views/tree-manage-view': 'bundles/kibokodam/js/app/views/tree-manage-view.js' + 'kibokodam/js/app/views/drag-and-drop': 'bundles/kibokodam/js/app/views/drag-and-drop.js' diff --git a/src/DAMBundle/Resources/config/services.yml b/src/DAMBundle/Resources/config/services.yml index 70927c9..ceaf104 100644 --- a/src/DAMBundle/Resources/config/services.yml +++ b/src/DAMBundle/Resources/config/services.yml @@ -99,3 +99,10 @@ services: tags: - { name: kernel.event_listener, event: oro_datagrid.datagrid.build.before.kiboko-dam-documents-grid, method: onBuildBefore } + kiboko_dam.document_manager.api: + class: Oro\Bundle\SoapBundle\Entity\Manager\ApiEntityManager + parent: oro_soap.manager.entity_manager.abstract + arguments: + - Kiboko\Bundle\DAMBundle\Entity\Document + - '@doctrine.orm.entity_manager' + diff --git a/src/DAMBundle/Resources/public/js/app/views/drag-and-drop.js b/src/DAMBundle/Resources/public/js/app/views/drag-and-drop.js new file mode 100644 index 0000000..ace8d03 --- /dev/null +++ b/src/DAMBundle/Resources/public/js/app/views/drag-and-drop.js @@ -0,0 +1,83 @@ +define(function(require) { + 'use strict'; + + var DragAndDropComponent; + + var BaseComponent = require('oroui/js/app/components/base/component'); + var $ = require('jquery'); + var _ = require('underscore'); + var tools = require('oroui/js/tools'); + + + function allowDrop(event) { + event.preventDefault(); + document.getElementsByClassName("drop-target").innerHTML = "The p element is OVER the droptarget."; + event.target.style.border = "10px dotted green"; + } + + function drop(event) { + event.preventDefault(); + + } + /** + * @export kibokodam/js/app/views/drag-and-drop + * @extends oroui.app.components.base.Component + * @class kibokodam.app.components.DragAndDrop + */ + DragAndDropComponent = BaseComponent.extend({ + /** + * @inheritDoc + */ + constructor: function PasswordGenerateComponent() { + DragAndDropComponent.__super__.constructor.apply(this, arguments); + }, + + initialize: function(options) { + + + // window.addEventListener("dragover",function(e){ + // e = e || event; + // e.preventDefault(); + // },false); + // window.addEventListener("drop",function(e){ + // e = e || event; + // e.preventDefault(); + // },false); + + $(".drop-target").find('*').addBack().on( + 'dragover', + function(e) { + } + ); + $('.drop-target').find('*').on( + 'dragenter', + function(e) { + var $this = $(this); + $this.css("opacity",0.2); + e.preventDefault(); + e.stopPropagation(); + + } + ); + $('.drop-target').find('*').on( + 'dragleave', + function(event) { + var $this = $(this); + $this.css("opacity",0.2); + e.preventDefault(); + e.stopPropagation(); + // var dataTransfer = e.originalEvent.dataTransfer; + // if( dataTransfer && dataTransfer.files.length) { + // e.preventDefault(); + // e.stopPropagation(); + // //more code here... + // } + } + ); + + + }, + }); + + return DragAndDropComponent; +}); diff --git a/src/DAMBundle/Resources/views/DocumentNode/browse.html.twig b/src/DAMBundle/Resources/views/DocumentNode/browse.html.twig index a70671f..94fb3ca 100644 --- a/src/DAMBundle/Resources/views/DocumentNode/browse.html.twig +++ b/src/DAMBundle/Resources/views/DocumentNode/browse.html.twig @@ -134,8 +134,8 @@
{% else %} -
-
+
+
{{ dataGrid.renderGrid('kiboko-dam-documents-grid', { parent: teamstorage.uuid }) }}
From 46acaacfcf8293216f1a8bbba6765037a51664c4 Mon Sep 17 00:00:00 2001 From: julien Date: Thu, 3 Jan 2019 12:01:27 +0100 Subject: [PATCH 19/42] Updated datagrid --- .../Resources/config/oro/datagrids.yml | 45 +++++++++++-------- .../Resources/translations/messages.en.yml | 8 ++++ .../Resources/translations/messages.fr_FR.yml | 8 ++++ 3 files changed, 43 insertions(+), 18 deletions(-) diff --git a/src/DAMBundle/Resources/config/oro/datagrids.yml b/src/DAMBundle/Resources/config/oro/datagrids.yml index 4948f42..aa96166 100644 --- a/src/DAMBundle/Resources/config/oro/datagrids.yml +++ b/src/DAMBundle/Resources/config/oro/datagrids.yml @@ -121,9 +121,14 @@ datagrids: select: - file.id AS fileId - file.filename AS fileName - - owner.username + - owner.username AS ownerName - document.id AS id - document.uuid AS uuid + - node.uuid AS parentUuid + - file.extension AS extension + - file.fileSize + - file.createdAt AS createdAt + - file.updatedAt AS updatedAt from: - { table: KibokoDAMBundle:Document, alias: document } join: @@ -145,9 +150,6 @@ datagrids: name: type: localized_value data_name: names - slug: - type: localized_value - data_name: slugs view_link: type: url route: kiboko_dam_document_view @@ -158,11 +160,11 @@ datagrids: route: kiboko_dam_document_update params: - uuid -# delete_link: -# type: url -# route: kiboko_api_delete_document -# params: -# - id + delete_link: + type: url + route: kiboko_api_delete_document + params: + document: id actions: view: acl_resource: kiboko_dam_document_view @@ -189,9 +191,20 @@ datagrids: name: label: kiboko.dam.document.datagrid.columns.name.label data_name: name - slug: - label: kiboko.dam.document.datagrid.columns.slug.label - data_name: slug + extension: + label: kiboko.dam.document.datagrid.columns.extension.label + data_name: extension + filesize: + label: kiboko.dam.document.datagrid.columns.filesize.label + data_name: fileSize + updatedat: + label: kiboko.dam.document.datagrid.columns.updatedat.label + data_name: updatedAt + frontend_type: datetime + createdat: + label: kiboko.dam.document.datagrid.columns.createdat.label + data_name: createdAt + frontend_type: datetime filename: label: kiboko.dam.document.datagrid.columns.thumbnail.label data_name: filename @@ -200,18 +213,14 @@ datagrids: template: KibokoDAMBundle:Document:Datagrid/Property/thumbnail.html.twig owner: label: kiboko.dam.document.datagrid.columns.owner.label - data_name: owner + data_name: ownerName sorters: columns: name: data_name: name - slug: - data_name: slug filters: columns: name: type: string data_name: name - slug: - type: string - data_name: slug + diff --git a/src/DAMBundle/Resources/translations/messages.en.yml b/src/DAMBundle/Resources/translations/messages.en.yml index 95d922a..df5025c 100644 --- a/src/DAMBundle/Resources/translations/messages.en.yml +++ b/src/DAMBundle/Resources/translations/messages.en.yml @@ -43,6 +43,14 @@ kiboko: label: Owner thumbnail: label: Thumbnail + extension: + label: Extension + filesize: + label: File size + createdat: + label: Created at + updatedat: + label: Updated At upload: ok: label: 'Document uploaded' diff --git a/src/DAMBundle/Resources/translations/messages.fr_FR.yml b/src/DAMBundle/Resources/translations/messages.fr_FR.yml index 467ed7b..8db1d5c 100644 --- a/src/DAMBundle/Resources/translations/messages.fr_FR.yml +++ b/src/DAMBundle/Resources/translations/messages.fr_FR.yml @@ -44,6 +44,14 @@ kiboko: label: Propriétaire thumbnail: label: Vignette + extension: + label: Extension + filesize: + label: Taille + createdat: + label: Créer le + updatedat: + label: Mis à jour le upload: ok: label: 'Document téléversé' From a0c5bd18bf1ec7d725e167f14d7b56f5a4c43944 Mon Sep 17 00:00:00 2001 From: julien Date: Thu, 3 Jan 2019 12:02:30 +0100 Subject: [PATCH 20/42] Updated create Node root in browse view --- .../Controller/DocumentNodeController.php | 45 ++++++++++++++----- .../DocumentDatagridListener.php | 1 + src/DAMBundle/Resources/config/services.yml | 2 + .../public/js/app/views/tree-manage-view.js | 6 ++- .../views/DocumentNode/browse.html.twig | 4 +- .../views/DocumentNode/update.html.twig | 5 ++- 6 files changed, 46 insertions(+), 17 deletions(-) diff --git a/src/DAMBundle/Controller/DocumentNodeController.php b/src/DAMBundle/Controller/DocumentNodeController.php index d64b2ac..149e4ee 100644 --- a/src/DAMBundle/Controller/DocumentNodeController.php +++ b/src/DAMBundle/Controller/DocumentNodeController.php @@ -6,6 +6,7 @@ use Kiboko\Bundle\DAMBundle\Entity\TeamStorageNode; use Kiboko\Bundle\DAMBundle\JsTree\DocumentNodeUpdateTreeHandler; use Kiboko\Bundle\DAMBundle\Model\DocumentNodeInterface; +use Kiboko\Bundle\DAMBundle\Provider\NodeProvider; use Oro\Bundle\FormBundle\Model\UpdateHandlerFacade; use Oro\Bundle\SecurityBundle\Annotation\Acl; use Sensio\Bundle\FrameworkExtraBundle\Configuration\ParamConverter; @@ -157,9 +158,11 @@ public function browseToNodeAction(TeamStorageNode $teamStorageNode, DocumentNod * @param Request $request * * @param DocumentNodeInterface $parent + * @param DocumentNodeInterface $root * @return array|Response * - * @Route("/{uuid}/create", + * + * @Route("/{uuid}/create/{root}", * name="kiboko_dam_node_create", * requirements={"uuid"="[\da-f]{8}-[\da-f]{4}-[\da-f]{4}-[\da-f]{4}-[\da-f]{12}"} * ) @@ -170,6 +173,13 @@ public function browseToNodeAction(TeamStorageNode $teamStorageNode, DocumentNod * "map_method_signature" = true, * } * ) + * @ParamConverter("root", + * class="KibokoDAMBundle:DocumentNode", + * options={ + * "mapping": {"root": "uuid"}, + * "map_method_signature" = true, + * } + * ) * @Acl( * id="kiboko_dam_node_create", * type="entity", @@ -178,21 +188,22 @@ public function browseToNodeAction(TeamStorageNode $teamStorageNode, DocumentNod * ) * @Template("KibokoDAMBundle:DocumentNode:update.html.twig") */ - public function createAction(Request $request, DocumentNodeInterface $parent) + public function createAction(Request $request, DocumentNodeInterface $parent,DocumentNodeInterface $root) { $node = new DocumentNode(); $node->setParent($parent); - return $this->update($request, $node); + return $this->update($request, $node,$root); } /** - * @param Request $request - * @param DocumentNodeInterface $node * + * @param Request $request + * @param DocumentNodeInterface $node + * @param DocumentNodeInterface|null $root * @return array|Response * - * @Route("/{uuid}/update", + * @Route("/{root}/update/{uuid}", * name="kiboko_dam_node_update", * requirements={"uuid"="[\da-f]{8}-[\da-f]{4}-[\da-f]{4}-[\da-f]{4}-[\da-f]{12}"} * ) @@ -202,6 +213,15 @@ public function createAction(Request $request, DocumentNodeInterface $parent) * "mapping": {"uuid": "uuid"}, * "map_method_signature" = true, * } + *) + * @ParamConverter("root", + * class="KibokoDAMBundle:DocumentNode", + * options={ + * "mapping": { + * "root": "uuid", + * }, + * "map_method_signature" = true, + * } * ) * @Acl( * id="kiboko_dam_node_edit", @@ -211,24 +231,27 @@ public function createAction(Request $request, DocumentNodeInterface $parent) * ) * @Template("KibokoDAMBundle:DocumentNode:update.html.twig") */ - public function editAction(Request $request, DocumentNodeInterface $node) + public function editAction(Request $request,DocumentNodeInterface $node, DocumentNodeInterface $root = null) { - return $this->update($request, $node); + return $this->update($request,$node,$root); } /** - * @param Request $request + * @param Request $request + * @param DocumentNodeInterface $root * @param DocumentNodeInterface $node * * @return array|Response */ - private function update(Request $request, DocumentNodeInterface $node) + private function update(Request $request,DocumentNodeInterface $node, DocumentNodeInterface $root = null) { return $this->handler->update( $node, $this->form, $this->translator->trans('kiboko.dam.documentnode.updated.label'), - $request + $request, + null, + new NodeProvider($root, $node, $this->form, $request) ); } } diff --git a/src/DAMBundle/EventListener/DocumentDatagridListener.php b/src/DAMBundle/EventListener/DocumentDatagridListener.php index 94b95f7..0d94bc6 100644 --- a/src/DAMBundle/EventListener/DocumentDatagridListener.php +++ b/src/DAMBundle/EventListener/DocumentDatagridListener.php @@ -4,6 +4,7 @@ use Doctrine\ORM\EntityManager; use Kiboko\Bundle\DAMBundle\Entity\DocumentNode; +use Oro\Bundle\DataGridBundle\Datasource\ResultRecordInterface; use Oro\Bundle\DataGridBundle\Event\BuildAfter; use Oro\Bundle\DataGridBundle\Event\BuildBefore; use Oro\Bundle\SecurityBundle\Tools\UUIDGenerator; diff --git a/src/DAMBundle/Resources/config/services.yml b/src/DAMBundle/Resources/config/services.yml index ceaf104..47d7d21 100644 --- a/src/DAMBundle/Resources/config/services.yml +++ b/src/DAMBundle/Resources/config/services.yml @@ -1,3 +1,5 @@ +parameters: + kiboko_dam.event_listener.document_filesize_formatter: Kiboko\Bundle\DAMBundle\EventListener\DocumentDatagridListener services: kiboko_dam.form.type.document: class: Kiboko\Bundle\DAMBundle\Form\Type\DocumentType diff --git a/src/DAMBundle/Resources/public/js/app/views/tree-manage-view.js b/src/DAMBundle/Resources/public/js/app/views/tree-manage-view.js index eb432c6..54ee6ae 100644 --- a/src/DAMBundle/Resources/public/js/app/views/tree-manage-view.js +++ b/src/DAMBundle/Resources/public/js/app/views/tree-manage-view.js @@ -45,22 +45,24 @@ define(function (require) { if(url.match(regex)) { url = url.match(regex); var nodeUuid = url.toString(); - var buttonUuid = nodeUuid; } if (nodeUuid) { $("div[class='grid-views']").ready(function(){ - mediator.trigger('datagrid:setParam:' + 'kiboko-dam-documents-grid', 'parent', buttonUuid); + mediator.trigger('datagrid:setParam:' + 'kiboko-dam-documents-grid', 'parent', nodeUuid); mediator.trigger('datagrid:doRefresh:' + 'kiboko-dam-documents-grid'); }); var str = 'node_'; var uploadWidget = $(".upload_button_widget"); + var createNodeWidget = $('.pull-right a'); + var hrefNodeCreate = createNodeWidget.attr("href"); var dataUrl = uploadWidget.attr('data-url'); var regexUuid = /\b[0-9a-f]{8}\b-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{4}-\b[0-9a-f]{12}\b/; uploadWidget.attr('data-url', dataUrl.replace(regexUuid, nodeUuid)); + createNodeWidget.attr('href',hrefNodeCreate.replace(regexUuid,nodeUuid)); nodeUuid = nodeUuid.replace(/-/g, '_'); nodeUuid = str.concat('', nodeUuid); this.jsTreeInstance._open_to(nodeUuid); diff --git a/src/DAMBundle/Resources/views/DocumentNode/browse.html.twig b/src/DAMBundle/Resources/views/DocumentNode/browse.html.twig index 94fb3ca..29aa33a 100644 --- a/src/DAMBundle/Resources/views/DocumentNode/browse.html.twig +++ b/src/DAMBundle/Resources/views/DocumentNode/browse.html.twig @@ -31,7 +31,7 @@
{{ UI.button({ - 'path' : path(routePrefix ~ 'create', { uuid: teamstorage.uuid }), + 'path' : path(routePrefix ~ 'create' , { uuid: teamstorage.uuid, root: teamstorage.uuid}), 'iCss': 'fa-folder', 'label': 'kiboko.dam.documentnode.create_label'|trans({ '%entityName%': 'kiboko.dam.documentnode.entity_label'|trans }), 'title': 'kiboko.dam.documentnode.create_label'|trans({ '%entityName%': 'kiboko.dam.documentnode.entity_label'|trans }) @@ -71,7 +71,7 @@ 'iCss': 'fa-plus', 'dataMethod': 'POST', 'dataRedirect': app.request.uri, - 'dataUrl': path(routePrefix ~ 'create', { uuid: teamstorage.uuid, parentKey: teamstorage.names|localized_value, 'isDivider': true }), + 'dataUrl': path(routePrefix ~ 'create', { uuid: teamstorage.uuid, parentKey: teamstorage.names|localized_value, 'isDivider': true, root: teamstorage.uuid }), 'successMessage': dividerCreatedMessage|default('kiboko.dam.documentnode.divider_created')|trans({'%reload_link%': reloadLink}) }) %} diff --git a/src/DAMBundle/Resources/views/DocumentNode/update.html.twig b/src/DAMBundle/Resources/views/DocumentNode/update.html.twig index 6f870d3..23c79b9 100644 --- a/src/DAMBundle/Resources/views/DocumentNode/update.html.twig +++ b/src/DAMBundle/Resources/views/DocumentNode/update.html.twig @@ -7,7 +7,7 @@ {% if node.id %} {% set formAction = path('kiboko_dam_node_update', { 'uuid': node.uuid }) %} {% else %} - {% set formAction = path('kiboko_dam_node_create', { 'uuid': node.parent.uuid }) %} + {% set formAction = path('kiboko_dam_node_create', { 'uuid': node.parent.uuid, 'root': node.parent.uuid }) %} {% endif %} {% block navButtons %} @@ -16,7 +16,7 @@ {% set html = UI.saveAndCloseButton({ 'route': 'kiboko_dam_node_browse', - 'params': {'uuid': node.parent.uuid} + 'params': {'uuid': root.uuid} }) %} {{ UI.dropdownSaveButton({'html': html}) }} @@ -39,6 +39,7 @@ {% endblock pageHeader %} {% block content_data %} + {% set id = 'document-node-edit' %} {% set dataBlocks = [{ 'title': 'General'|trans, From 68c929227830be174b1b3d7f03bd8bab8f89ac12 Mon Sep 17 00:00:00 2001 From: julien Date: Thu, 3 Jan 2019 17:13:06 +0100 Subject: [PATCH 21/42] Changed document node widget route --- .../Controller/DocumentNodeController.php | 2 +- src/DAMBundle/Provider/NodeProvider.php | 57 +++++++++++ .../public/js/app/views/tree-manage-view.js | 95 ++++++++++++++----- .../Resources/translations/messages.en.yml | 2 + .../views/DocumentNode/update.html.twig | 7 +- 5 files changed, 134 insertions(+), 29 deletions(-) create mode 100644 src/DAMBundle/Provider/NodeProvider.php diff --git a/src/DAMBundle/Controller/DocumentNodeController.php b/src/DAMBundle/Controller/DocumentNodeController.php index 149e4ee..33039a5 100644 --- a/src/DAMBundle/Controller/DocumentNodeController.php +++ b/src/DAMBundle/Controller/DocumentNodeController.php @@ -162,7 +162,7 @@ public function browseToNodeAction(TeamStorageNode $teamStorageNode, DocumentNod * @return array|Response * * - * @Route("/{uuid}/create/{root}", + * @Route("/{root}/create/{uuid}", * name="kiboko_dam_node_create", * requirements={"uuid"="[\da-f]{8}-[\da-f]{4}-[\da-f]{4}-[\da-f]{4}-[\da-f]{12}"} * ) diff --git a/src/DAMBundle/Provider/NodeProvider.php b/src/DAMBundle/Provider/NodeProvider.php new file mode 100644 index 0000000..f4f8278 --- /dev/null +++ b/src/DAMBundle/Provider/NodeProvider.php @@ -0,0 +1,57 @@ +root = $root; + $this->node = $node; + $this->form = $form; + $this->request = $request; + } + + /** + * @param object $entity + * @param FormInterface $form + * @param Request $request + * @return array + */ + public function getData($entity, FormInterface $form, Request $request) + { + return [ + 'form' => $this->form->createView(), + 'root' => $this->root, + ]; + } +} \ No newline at end of file diff --git a/src/DAMBundle/Resources/public/js/app/views/tree-manage-view.js b/src/DAMBundle/Resources/public/js/app/views/tree-manage-view.js index 54ee6ae..99b8b2f 100644 --- a/src/DAMBundle/Resources/public/js/app/views/tree-manage-view.js +++ b/src/DAMBundle/Resources/public/js/app/views/tree-manage-view.js @@ -28,45 +28,86 @@ define(function (require) { 'ready.jstree': 'onTreeLoaded', }, + uploadWidget: null, + createNodeWidget: null, + /** * @inheritDoc */ constructor: function TreeManageView() { TreeManageView.__super__.constructor.apply(this, arguments); + this.uploadWidget = $(".upload_button_widget"); + this.createNodeWidget = $('.pull-right a'); }, + /** + * Format uuid + * @param chain + * @returns {*} + */ formatUuuid: function (chain) { return chain.substr(5).replace(/_/g, '-'); }, - onTreeLoaded: function (e, data) { - var url = window.location.pathname; - var regex = /(?<=browse\/).*$/g; - if(url.match(regex)) { - url = url.match(regex); - var nodeUuid = url.toString(); + /** + * Refresh document datagrid at uuid node provided + * @param nodeUuid + */ + reloadDocumentGrid: function (nodeUuid) { + + $("div[class='grid-views']").ready(function(){ + mediator.trigger('datagrid:setParam:' + 'kiboko-dam-documents-grid', 'parent', nodeUuid); + mediator.trigger('datagrid:doRefresh:' + 'kiboko-dam-documents-grid'); + }); + }, + + /** + * Refresh JsTree selection at uuid provided + * @param nodeUuid + */ + refreshJsTree: function (nodeUuid) { + + var str = 'node_'; + nodeUuid = nodeUuid.replace(/-/g, '_'); + nodeUuid = str.concat('', nodeUuid); + this.jsTreeInstance._open_to(nodeUuid); + this.jsTreeInstance.select_node(nodeUuid); + }, + + /** + * Refresh buttons route with uuid provided + * @param nodeUuid + */ + refreshButtonsRoute: function (nodeUuid) { + + var hrefNodeCreate = this.createNodeWidget.attr("href"); + var dataUrl = this.uploadWidget.attr('data-url'); + var regexUuid = /\b[0-9a-f]{8}\b-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{4}-\b[0-9a-f]{12}\b/; + this.uploadWidget.attr('data-url', dataUrl.replace(regexUuid, nodeUuid)); + var regexUuid2 = /(?<=create\/).*$/; + + this.createNodeWidget.attr('href',hrefNodeCreate.replace(regexUuid2,nodeUuid)); + }, + + /** + * Update document grid, buttons route and tree position after page reload + * @param event + * @param data + */ + onTreeLoaded: function (event, data) { + var path = window.location.pathname; + var regexChildUuid = /(?<=browse\/).*$/g; + if(path.match(regexChildUuid)) { + var nodeUuid = path.match(regexChildUuid).toString(); } if (nodeUuid) { - $("div[class='grid-views']").ready(function(){ - mediator.trigger('datagrid:setParam:' + 'kiboko-dam-documents-grid', 'parent', nodeUuid); - mediator.trigger('datagrid:doRefresh:' + 'kiboko-dam-documents-grid'); - }); + this.reloadDocumentGrid(nodeUuid); + this.refreshButtonsRoute(nodeUuid); + this.refreshJsTree(nodeUuid); - var str = 'node_'; - var uploadWidget = $(".upload_button_widget"); - var createNodeWidget = $('.pull-right a'); - var hrefNodeCreate = createNodeWidget.attr("href"); - var dataUrl = uploadWidget.attr('data-url'); - var regexUuid = /\b[0-9a-f]{8}\b-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{4}-\b[0-9a-f]{12}\b/; - uploadWidget.attr('data-url', dataUrl.replace(regexUuid, nodeUuid)); - createNodeWidget.attr('href',hrefNodeCreate.replace(regexUuid,nodeUuid)); - nodeUuid = nodeUuid.replace(/-/g, '_'); - nodeUuid = str.concat('', nodeUuid); - this.jsTreeInstance._open_to(nodeUuid); - this.jsTreeInstance.select_node(nodeUuid); } }, @@ -79,6 +120,7 @@ define(function (require) { onDragStop: function (e, data) { }, + /** * Triggers after node deleted in tree * @@ -103,14 +145,17 @@ define(function (require) { * @param {Object} data */ onNodeOpen: function (e, data) { + + var url = window.location.pathname; var regex = /browse(.*)/g; var newUrl = 'browse/'; newUrl += this.formatUuuid(data.node.id); window.history.pushState("", "", url.replace(regex,newUrl)); - mediator.trigger('datagrid:setParam:' + 'kiboko-dam-documents-grid', 'parent', this.formatUuuid(data.node.original.id)); - mediator.trigger('datagrid:doRefresh:' + 'kiboko-dam-documents-grid'); + + this.reloadDocumentGrid(this.formatUuuid(data.node.id)); + this.refreshButtonsRoute(this.formatUuuid(data.node.id)); }, /** * Triggers after node deleted in tree @@ -144,6 +189,7 @@ define(function (require) { } }, + /** * Triggers after node change name * @@ -167,6 +213,7 @@ define(function (require) { } } }, + /** * Triggers after node change creation * diff --git a/src/DAMBundle/Resources/translations/messages.en.yml b/src/DAMBundle/Resources/translations/messages.en.yml index df5025c..195122d 100644 --- a/src/DAMBundle/Resources/translations/messages.en.yml +++ b/src/DAMBundle/Resources/translations/messages.en.yml @@ -72,6 +72,8 @@ kiboko: label: 'Cancel' save: label: 'Save' + general: + label: General teamstorage: index: entity: diff --git a/src/DAMBundle/Resources/views/DocumentNode/update.html.twig b/src/DAMBundle/Resources/views/DocumentNode/update.html.twig index 23c79b9..c258e32 100644 --- a/src/DAMBundle/Resources/views/DocumentNode/update.html.twig +++ b/src/DAMBundle/Resources/views/DocumentNode/update.html.twig @@ -16,7 +16,7 @@ {% set html = UI.saveAndCloseButton({ 'route': 'kiboko_dam_node_browse', - 'params': {'uuid': root.uuid} + 'params': {uuid: root.uuid} }) %} {{ UI.dropdownSaveButton({'html': html}) }} @@ -28,18 +28,17 @@ {% set breadcrumbs = { 'entity': node, 'indexPath': path('kiboko_dam_index'), - 'indexLabel': 'Team Storage'|trans, + 'indexLabel': 'kiboko.dam.documentnode.entity_label'|trans, 'entityTitle': node.names|localized_value } %} {{ parent() }} {% else %} - {% set title = 'oro.ui.create_entity'|trans({ '%entityName%': 'Team Storage'|trans }) %} + {% set title = 'oro.ui.create_entity'|trans({ '%entityName%': 'kiboko.dam.documentnode.entity_label'|trans }) %} {{ include('OroUIBundle::page_title_block.html.twig', { title: title }) }} {% endif %} {% endblock pageHeader %} {% block content_data %} - {% set id = 'document-node-edit' %} {% set dataBlocks = [{ 'title': 'General'|trans, From 45a3ce2797f3e931ca4a0490c44157b0c0a20bea Mon Sep 17 00:00:00 2001 From: julien Date: Fri, 4 Jan 2019 11:23:03 +0100 Subject: [PATCH 22/42] Changed the way js tree automaticly open selected node in browse to node route --- .../Controller/DocumentNodeController.php | 2 +- .../JsTree/DocumentNodeUpdateTreeHandler.php | 25 +++++++++++++------ .../public/js/app/views/tree-manage-view.js | 25 +++---------------- 3 files changed, 22 insertions(+), 30 deletions(-) diff --git a/src/DAMBundle/Controller/DocumentNodeController.php b/src/DAMBundle/Controller/DocumentNodeController.php index 33039a5..0194905 100644 --- a/src/DAMBundle/Controller/DocumentNodeController.php +++ b/src/DAMBundle/Controller/DocumentNodeController.php @@ -150,7 +150,7 @@ public function browseToNodeAction(TeamStorageNode $teamStorageNode, DocumentNod 'teamstorage' => $teamStorageNode, 'node' => $node, 'path' => $path, - 'tree' => $this->treeHandler->createTree($teamStorageNode), + 'tree' => $this->treeHandler->createTree($teamStorageNode, $node), ]; } diff --git a/src/DAMBundle/JsTree/DocumentNodeUpdateTreeHandler.php b/src/DAMBundle/JsTree/DocumentNodeUpdateTreeHandler.php index 4984cda..84c93be 100644 --- a/src/DAMBundle/JsTree/DocumentNodeUpdateTreeHandler.php +++ b/src/DAMBundle/JsTree/DocumentNodeUpdateTreeHandler.php @@ -53,9 +53,10 @@ public function __construct( /** * @param TeamStorageNode $root * + * @param DocumentNodeInterface $node * @return array */ - public function createTree(TeamStorageNode $root): array + public function createTree(TeamStorageNode $root, DocumentNodeInterface $node = null): array { if ($root === null) { return []; @@ -63,7 +64,7 @@ public function createTree(TeamStorageNode $root): array $tree = $this->getNodes($root); - return $this->formatTree($tree, $root); + return $this->formatTree($tree, $root, $node); } /** @@ -86,16 +87,22 @@ private function getNodes(DocumentNodeInterface $node) /** * @param DocumentNodeInterface[] $entities - * @param DocumentNodeInterface $root + * @param DocumentNodeInterface $root * + * @param DocumentNodeInterface $node * @return array */ - private function formatTree(array $entities, DocumentNodeInterface $root) + private function formatTree(array $entities, DocumentNodeInterface $root, DocumentNodeInterface $node = null) { $formattedTree = []; - + $uuidOpenedNode = null; foreach ($entities as $entity) { - $node = $this->formatEntity($root, $entity); + if( $entity === $node){ + $node = $this->formatEntity($root, $entity, true); + } + else { + $node = $this->formatEntity($root, $entity); + } $formattedTree[] = $node; } @@ -139,6 +146,7 @@ private function formatEntity(TeamStorageNode $root, DocumentNodeInterface $enti 'state' => [ 'opened' => $isOpened, 'disabled' => false, + 'selected' => $isOpened, ], //'li_attr' => !$entity->isDisplayed() ? ['class' => 'hidden'] : [] ]; @@ -147,11 +155,12 @@ private function formatEntity(TeamStorageNode $root, DocumentNodeInterface $enti /** * @param DocumentNodeInterface|null $root * + * @param DocumentNodeInterface|null $node * @return TreeItem[] */ - public function getTreeItemList(DocumentNodeInterface $root = null) + public function getTreeItemList(DocumentNodeInterface $root = null, DocumentNodeInterface $node = null) { - $nodes = $this->createTree($root); + $nodes = $this->createTree($root,$node); $items = []; diff --git a/src/DAMBundle/Resources/public/js/app/views/tree-manage-view.js b/src/DAMBundle/Resources/public/js/app/views/tree-manage-view.js index 99b8b2f..62036ea 100644 --- a/src/DAMBundle/Resources/public/js/app/views/tree-manage-view.js +++ b/src/DAMBundle/Resources/public/js/app/views/tree-manage-view.js @@ -61,32 +61,16 @@ define(function (require) { }); }, - /** - * Refresh JsTree selection at uuid provided - * @param nodeUuid - */ - refreshJsTree: function (nodeUuid) { - - var str = 'node_'; - nodeUuid = nodeUuid.replace(/-/g, '_'); - nodeUuid = str.concat('', nodeUuid); - this.jsTreeInstance._open_to(nodeUuid); - this.jsTreeInstance.select_node(nodeUuid); - }, - /** * Refresh buttons route with uuid provided * @param nodeUuid */ refreshButtonsRoute: function (nodeUuid) { - var hrefNodeCreate = this.createNodeWidget.attr("href"); - var dataUrl = this.uploadWidget.attr('data-url'); - var regexUuid = /\b[0-9a-f]{8}\b-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{4}-\b[0-9a-f]{12}\b/; - this.uploadWidget.attr('data-url', dataUrl.replace(regexUuid, nodeUuid)); - var regexUuid2 = /(?<=create\/).*$/; - - this.createNodeWidget.attr('href',hrefNodeCreate.replace(regexUuid2,nodeUuid)); + this.createNodeWidget.attr('href', routing.generate('kiboko_dam_node_create', { + 'uuid': nodeUuid, + 'root': null + })); }, /** @@ -106,7 +90,6 @@ define(function (require) { this.reloadDocumentGrid(nodeUuid); this.refreshButtonsRoute(nodeUuid); - this.refreshJsTree(nodeUuid); } }, From 5ed7196a3d8cc0ca67e194c1ef9eb9ba36f3c1ff Mon Sep 17 00:00:00 2001 From: julien Date: Fri, 4 Jan 2019 14:12:39 +0100 Subject: [PATCH 23/42] Changed wrong name file for the installer --- ...bokoDAMLogBundleInstaller.php => KibokoDAMBundleInstaller.php} | 0 1 file changed, 0 insertions(+), 0 deletions(-) rename src/DAMBundle/Migrations/Schema/{KibokoDAMLogBundleInstaller.php => KibokoDAMBundleInstaller.php} (100%) diff --git a/src/DAMBundle/Migrations/Schema/KibokoDAMLogBundleInstaller.php b/src/DAMBundle/Migrations/Schema/KibokoDAMBundleInstaller.php similarity index 100% rename from src/DAMBundle/Migrations/Schema/KibokoDAMLogBundleInstaller.php rename to src/DAMBundle/Migrations/Schema/KibokoDAMBundleInstaller.php From 172404db887932690cd70740fdc8abf946c995a9 Mon Sep 17 00:00:00 2001 From: julien Date: Fri, 4 Jan 2019 17:11:38 +0100 Subject: [PATCH 24/42] fix one route in js fix indent --- .../Controller/DocumentNodeController.php | 8 ++- .../DocumentNodeTreeAjaxController.php | 50 ++++++++++--------- .../public/js/app/views/tree-manage-view.js | 23 ++++----- 3 files changed, 42 insertions(+), 39 deletions(-) diff --git a/src/DAMBundle/Controller/DocumentNodeController.php b/src/DAMBundle/Controller/DocumentNodeController.php index 0194905..a01b34d 100644 --- a/src/DAMBundle/Controller/DocumentNodeController.php +++ b/src/DAMBundle/Controller/DocumentNodeController.php @@ -164,7 +164,13 @@ public function browseToNodeAction(TeamStorageNode $teamStorageNode, DocumentNod * * @Route("/{root}/create/{uuid}", * name="kiboko_dam_node_create", - * requirements={"uuid"="[\da-f]{8}-[\da-f]{4}-[\da-f]{4}-[\da-f]{4}-[\da-f]{12}"} + * requirements={ + * "root"="[\da-f]{8}-[\da-f]{4}-[\da-f]{4}-[\da-f]{4}-[\da-f]{12}", + * "uuid"="[\da-f]{8}-[\da-f]{4}-[\da-f]{4}-[\da-f]{4}-[\da-f]{12}" + * }, + * options={ + * "expose"=true, + * } * ) * @ParamConverter("parent", * class="KibokoDAMBundle:DocumentNode", diff --git a/src/DAMBundle/Controller/DocumentNodeTreeAjaxController.php b/src/DAMBundle/Controller/DocumentNodeTreeAjaxController.php index c660944..ddf6186 100644 --- a/src/DAMBundle/Controller/DocumentNodeTreeAjaxController.php +++ b/src/DAMBundle/Controller/DocumentNodeTreeAjaxController.php @@ -106,35 +106,37 @@ public function deleteAction(Request $request, DocumentNodeInterface $node) * * {@inheritdoc} */ - public function renameAction(Request $request, DocumentNodeInterface $node) - { - $newName = $request->get('newName'); - - /** @var DocumentNode $oldNode */ + public function renameAction(Request $request, DocumentNodeInterface $node) + { + $newName = $request->get('newName'); - $oldName = $node->getLocaleName($this->localizationHelper); - $oldName->setString($newName); + /** @var DocumentNode $oldNode */ - $collection = new ArrayCollection(); - $collection->add($oldName); + $oldName = $node->getLocaleName($this->localizationHelper); + $oldName->setString($newName); - $node->setNames($collection); + $collection = new ArrayCollection(); + $collection->add($oldName); - try { - $this->em->persist($node); - $this->em->flush(); - } - catch (ORMException $e) { - return new JsonResponse($e->getMessage(),500); - } + $node->setNames($collection); - return new JsonResponse('renamed',200); + try { + $this->em->persist($node); + $this->em->flush(); + } + catch (ORMException $e) { + return new JsonResponse($e->getMessage(),500); } + return new JsonResponse('renamed',200); + } + /** * @Route("/create/{uuid}", * name="kiboko_dam_document_node_tree_ajax_create", - * requirements={"uuid"="[\da-f]{8}-[\da-f]{4}-[\da-f]{4}-[\da-f]{4}-[\da-f]{12}"}, + * requirements={ + * "uuid"="[\da-f]{8}-[\da-f]{4}-[\da-f]{4}-[\da-f]{4}-[\da-f]{12}" + * }, * options={ * "expose"=true, * }, @@ -152,11 +154,11 @@ public function renameAction(Request $request, DocumentNodeInterface $node) * * {@inheritdoc} */ - public function createNodeAction(Request $request, DocumentNodeInterface $node) - { - $name= $request->get('name'); - return $this->handler->createNode($node,$name); - } + public function createNodeAction(Request $request, DocumentNodeInterface $node) + { + $name = $request->get('name'); + return $this->handler->createNode($node, $name); + } /** * @Route("/move/{uuid}/to/{uuidParent}", diff --git a/src/DAMBundle/Resources/public/js/app/views/tree-manage-view.js b/src/DAMBundle/Resources/public/js/app/views/tree-manage-view.js index 62036ea..5b0ae25 100644 --- a/src/DAMBundle/Resources/public/js/app/views/tree-manage-view.js +++ b/src/DAMBundle/Resources/public/js/app/views/tree-manage-view.js @@ -31,11 +31,14 @@ define(function (require) { uploadWidget: null, createNodeWidget: null, + rootUuid: null, + /** * @inheritDoc */ constructor: function TreeManageView() { TreeManageView.__super__.constructor.apply(this, arguments); + this.rootUuid = arguments[0].menu; this.uploadWidget = $(".upload_button_widget"); this.createNodeWidget = $('.pull-right a'); }, @@ -69,8 +72,9 @@ define(function (require) { this.createNodeWidget.attr('href', routing.generate('kiboko_dam_node_create', { 'uuid': nodeUuid, - 'root': null + 'root': this.rootUuid })); + }, /** @@ -120,6 +124,9 @@ define(function (require) { type: 'DELETE', url: url }); + // Todo: update url correclty + // window.history.pushState("object or string", "Title", "/new-url"); + }, /** * Triggers after node is opened @@ -129,7 +136,6 @@ define(function (require) { */ onNodeOpen: function (e, data) { - var url = window.location.pathname; var regex = /browse(.*)/g; var newUrl = 'browse/'; @@ -210,7 +216,6 @@ define(function (require) { if (data.node.original.uuid !== '') { var url = routing.generate('kiboko_dam_document_node_tree_ajax_create', {uuid: this.formatUuuid(parent)}); $.ajax({ - async: true, type: 'POST', data: { 'name': name, @@ -320,17 +325,7 @@ define(function (require) { "seperator_after": false, "label": _.__('kiboko.dam.js.jstree.contextmenu.newfolder.label'), action: function (data) { - var inst = $.jstree.reference(data.reference), - obj = inst.get_node(data.reference); - inst.create_node(obj, {}, "last", function (new_node) { - try { - inst.edit(new_node); - } catch (ex) { - setTimeout(function () { - inst.edit(new_node); - }, 0); - } - }); + tree.create_node($node, { text: _.__('kiboko.dam.js.jstree.contextmenu.newfolder.label'), type: 'default' }); tree.deselect_all(); tree.select_node($node); } From 03754a1c1675066a0ec51585a218082491f29557 Mon Sep 17 00:00:00 2001 From: xavier Date: Thu, 17 Jan 2019 10:21:39 +0100 Subject: [PATCH 25/42] Add missing file --- var/php/cssmin-v3.0.1.php | 5107 +++++++++++++++++++++++++++++++++++++ 1 file changed, 5107 insertions(+) create mode 100644 var/php/cssmin-v3.0.1.php diff --git a/var/php/cssmin-v3.0.1.php b/var/php/cssmin-v3.0.1.php new file mode 100644 index 0000000..1ed3d66 --- /dev/null +++ b/var/php/cssmin-v3.0.1.php @@ -0,0 +1,5107 @@ + + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN + * THE SOFTWARE. + * -- + * + * @package CssMin + * @link http://code.google.com/p/cssmin/ + * @author Joe Scylla + * @copyright 2008 - 2011 Joe Scylla + * @license http://opensource.org/licenses/mit-license.php MIT License + * @version 3.0.1 + * @codingStandardsIgnoreFile + */ +/** + * Abstract definition of a CSS token class. + * + * Every token has to extend this class. + * + * @package CssMin/Tokens + * @link http://code.google.com/p/cssmin/ + * @author Joe Scylla + * @copyright 2008 - 2011 Joe Scylla + * @license http://opensource.org/licenses/mit-license.php MIT License + * @version 3.0.1 + */ +abstract class aCssToken + { + /** + * Returns the token as string. + * + * @return string + */ + abstract public function __toString(); + } + +/** + * Abstract definition of a for a ruleset start token. + * + * @package CssMin/Tokens + * @link http://code.google.com/p/cssmin/ + * @author Joe Scylla + * @copyright 2008 - 2011 Joe Scylla + * @license http://opensource.org/licenses/mit-license.php MIT License + * @version 3.0.1 + */ +abstract class aCssRulesetStartToken extends aCssToken + { + + } + +/** + * Abstract definition of a for ruleset end token. + * + * @package CssMin/Tokens + * @link http://code.google.com/p/cssmin/ + * @author Joe Scylla + * @copyright 2008 - 2011 Joe Scylla + * @license http://opensource.org/licenses/mit-license.php MIT License + * @version 3.0.1 + */ +abstract class aCssRulesetEndToken extends aCssToken + { + /** + * Implements {@link aCssToken::__toString()}. + * + * @return string + */ + public function __toString() + { + return "}"; + } + } + +/** + * Abstract definition of a parser plugin. + * + * Every parser plugin have to extend this class. A parser plugin contains the logic to parse one or aspects of a + * stylesheet. + * + * @package CssMin/Parser/Plugins + * @link http://code.google.com/p/cssmin/ + * @author Joe Scylla + * @copyright 2008 - 2011 Joe Scylla + * @license http://opensource.org/licenses/mit-license.php MIT License + * @version 3.0.1 + */ +abstract class aCssParserPlugin + { + /** + * Plugin configuration. + * + * @var array + */ + protected $configuration = array(); + /** + * The CssParser of the plugin. + * + * @var CssParser + */ + protected $parser = null; + /** + * Plugin buffer. + * + * @var string + */ + protected $buffer = ""; + /** + * Constructor. + * + * @param CssParser $parser The CssParser object of this plugin. + * @param array $configuration Plugin configuration [optional] + * @return void + */ + public function __construct(CssParser $parser, array $configuration = null) + { + $this->configuration = $configuration; + $this->parser = $parser; + } + /** + * Returns the array of chars triggering the parser plugin. + * + * @return array + */ + abstract public function getTriggerChars(); + /** + * Returns the array of states triggering the parser plugin or FALSE if every state will trigger the parser plugin. + * + * @return array + */ + abstract public function getTriggerStates(); + /** + * Parser routine of the plugin. + * + * @param integer $index Current index + * @param string $char Current char + * @param string $previousChar Previous char + * @return mixed TRUE will break the processing; FALSE continue with the next plugin; integer set a new index and break the processing + */ + abstract public function parse($index, $char, $previousChar, $state); + } + +/** + * Abstract definition of a minifier plugin class. + * + * Minifier plugin process the parsed tokens one by one to apply changes to the token. Every minifier plugin has to + * extend this class. + * + * @package CssMin/Minifier/Plugins + * @link http://code.google.com/p/cssmin/ + * @author Joe Scylla + * @copyright 2008 - 2011 Joe Scylla + * @license http://opensource.org/licenses/mit-license.php MIT License + * @version 3.0.1 + */ +abstract class aCssMinifierPlugin + { + /** + * Plugin configuration. + * + * @var array + */ + protected $configuration = array(); + /** + * The CssMinifier of the plugin. + * + * @var CssMinifier + */ + protected $minifier = null; + /** + * Constructor. + * + * @param CssMinifier $minifier The CssMinifier object of this plugin. + * @param array $configuration Plugin configuration [optional] + * @return void + */ + public function __construct(CssMinifier $minifier, array $configuration = array()) + { + $this->configuration = $configuration; + $this->minifier = $minifier; + } + /** + * Apply the plugin to the token. + * + * @param aCssToken $token Token to process + * @return boolean Return TRUE to break the processing of this token; FALSE to continue + */ + abstract public function apply(aCssToken &$token); + /** + * -- + * + * @return array + */ + abstract public function getTriggerTokens(); + } + +/** + * Abstract definition of a minifier filter class. + * + * Minifier filters allows a pre-processing of the parsed token to add, edit or delete tokens. Every minifier filter + * has to extend this class. + * + * @package CssMin/Minifier/Filters + * @link http://code.google.com/p/cssmin/ + * @author Joe Scylla + * @copyright 2008 - 2011 Joe Scylla + * @license http://opensource.org/licenses/mit-license.php MIT License + * @version 3.0.1 + */ +abstract class aCssMinifierFilter + { + /** + * Filter configuration. + * + * @var array + */ + protected $configuration = array(); + /** + * The CssMinifier of the filter. + * + * @var CssMinifier + */ + protected $minifier = null; + /** + * Constructor. + * + * @param CssMinifier $minifier The CssMinifier object of this plugin. + * @param array $configuration Filter configuration [optional] + * @return void + */ + public function __construct(CssMinifier $minifier, array $configuration = array()) + { + $this->configuration = $configuration; + $this->minifier = $minifier; + } + /** + * Filter the tokens. + * + * @param array $tokens Array of objects of type aCssToken + * @return integer Count of added, changed or removed tokens; a return value large than 0 will rebuild the array + */ + abstract public function apply(array &$tokens); + } + +/** + * Abstract formatter definition. + * + * Every formatter have to extend this class. + * + * @package CssMin/Formatter + * @link http://code.google.com/p/cssmin/ + * @author Joe Scylla + * @copyright 2008 - 2011 Joe Scylla + * @license http://opensource.org/licenses/mit-license.php MIT License + * @version 3.0.1 + */ +abstract class aCssFormatter + { + /** + * Indent string. + * + * @var string + */ + protected $indent = " "; + /** + * Declaration padding. + * + * @var integer + */ + protected $padding = 0; + /** + * Tokens. + * + * @var array + */ + protected $tokens = array(); + /** + * Constructor. + * + * @param array $tokens Array of CssToken + * @param string $indent Indent string [optional] + * @param integer $padding Declaration value padding [optional] + */ + public function __construct(array $tokens, $indent = null, $padding = null) + { + $this->tokens = $tokens; + $this->indent = !is_null($indent) ? $indent : $this->indent; + $this->padding = !is_null($padding) ? $padding : $this->padding; + } + /** + * Returns the array of aCssToken as formatted string. + * + * @return string + */ + abstract public function __toString(); + } + +/** + * Abstract definition of a ruleset declaration token. + * + * @package CssMin/Tokens + * @link http://code.google.com/p/cssmin/ + * @author Joe Scylla + * @copyright 2008 - 2011 Joe Scylla + * @license http://opensource.org/licenses/mit-license.php MIT License + * @version 3.0.1 + */ +abstract class aCssDeclarationToken extends aCssToken + { + /** + * Is the declaration flagged as important? + * + * @var boolean + */ + public $IsImportant = false; + /** + * Is the declaration flagged as last one of the ruleset? + * + * @var boolean + */ + public $IsLast = false; + /** + * Property name of the declaration. + * + * @var string + */ + public $Property = ""; + /** + * Value of the declaration. + * + * @var string + */ + public $Value = ""; + /** + * Set the properties of the @font-face declaration. + * + * @param string $property Property of the declaration + * @param string $value Value of the declaration + * @param boolean $isImportant Is the !important flag is set? + * @param boolean $IsLast Is the declaration the last one of the block? + * @return void + */ + public function __construct($property, $value, $isImportant = false, $isLast = false) + { + $this->Property = $property; + $this->Value = $value; + $this->IsImportant = $isImportant; + $this->IsLast = $isLast; + } + /** + * Implements {@link aCssToken::__toString()}. + * + * @return string + */ + public function __toString() + { + return $this->Property . ":" . $this->Value . ($this->IsImportant ? " !important" : "") . ($this->IsLast ? "" : ";"); + } + } + +/** + * Abstract definition of a for at-rule block start token. + * + * @package CssMin/Tokens + * @link http://code.google.com/p/cssmin/ + * @author Joe Scylla + * @copyright 2008 - 2011 Joe Scylla + * @license http://opensource.org/licenses/mit-license.php MIT License + * @version 3.0.1 + */ +abstract class aCssAtBlockStartToken extends aCssToken + { + + } + +/** + * Abstract definition of a for at-rule block end token. + * + * @package CssMin/Tokens + * @link http://code.google.com/p/cssmin/ + * @author Joe Scylla + * @copyright 2008 - 2011 Joe Scylla + * @license http://opensource.org/licenses/mit-license.php MIT License + * @version 3.0.1 + */ +abstract class aCssAtBlockEndToken extends aCssToken + { + /** + * Implements {@link aCssToken::__toString()}. + * + * @return string + */ + public function __toString() + { + return "}"; + } + } + +/** + * {@link aCssFromatter Formatter} returning the CSS source in {@link http://goo.gl/etzLs Whitesmiths indent style}. + * + * @package CssMin/Formatter + * @link http://code.google.com/p/cssmin/ + * @author Joe Scylla + * @copyright 2008 - 2011 Joe Scylla + * @license http://opensource.org/licenses/mit-license.php MIT License + * @version 3.0.1 + */ +class CssWhitesmithsFormatter extends aCssFormatter + { + /** + * Implements {@link aCssFormatter::__toString()}. + * + * @return string + */ + public function __toString() + { + $r = array(); + $level = 0; + for ($i = 0, $l = count($this->tokens); $i < $l; $i++) + { + $token = $this->tokens[$i]; + $class = get_class($token); + $indent = str_repeat($this->indent, $level); + if ($class === "CssCommentToken") + { + $lines = array_map("trim", explode("\n", $token->Comment)); + for ($ii = 0, $ll = count($lines); $ii < $ll; $ii++) + { + $r[] = $indent . (substr($lines[$ii], 0, 1) == "*" ? " " : "") . $lines[$ii]; + } + } + elseif ($class === "CssAtCharsetToken") + { + $r[] = $indent . "@charset " . $token->Charset . ";"; + } + elseif ($class === "CssAtFontFaceStartToken") + { + $r[] = $indent . "@font-face"; + $r[] = $this->indent . $indent . "{"; + $level++; + } + elseif ($class === "CssAtImportToken") + { + $r[] = $indent . "@import " . $token->Import . " " . implode(", ", $token->MediaTypes) . ";"; + } + elseif ($class === "CssAtKeyframesStartToken") + { + $r[] = $indent . "@keyframes \"" . $token->Name . "\""; + $r[] = $this->indent . $indent . "{"; + $level++; + } + elseif ($class === "CssAtMediaStartToken") + { + $r[] = $indent . "@media " . implode(", ", $token->MediaTypes); + $r[] = $this->indent . $indent . "{"; + $level++; + } + elseif ($class === "CssAtPageStartToken") + { + $r[] = $indent . "@page"; + $r[] = $this->indent . $indent . "{"; + $level++; + } + elseif ($class === "CssAtVariablesStartToken") + { + $r[] = $indent . "@variables " . implode(", ", $token->MediaTypes); + $r[] = $this->indent . $indent . "{"; + $level++; + } + elseif ($class === "CssRulesetStartToken" || $class === "CssAtKeyframesRulesetStartToken") + { + $r[] = $indent . implode(", ", $token->Selectors); + $r[] = $this->indent . $indent . "{"; + $level++; + } + elseif ($class == "CssAtFontFaceDeclarationToken" + || $class === "CssAtKeyframesRulesetDeclarationToken" + || $class === "CssAtPageDeclarationToken" + || $class == "CssAtVariablesDeclarationToken" + || $class === "CssRulesetDeclarationToken" + ) + { + $declaration = $indent . $token->Property . ": "; + if ($this->padding) + { + $declaration = str_pad($declaration, $this->padding, " ", STR_PAD_RIGHT); + } + $r[] = $declaration . $token->Value . ($token->IsImportant ? " !important" : "") . ";"; + } + elseif ($class === "CssAtFontFaceEndToken" + || $class === "CssAtMediaEndToken" + || $class === "CssAtKeyframesEndToken" + || $class === "CssAtKeyframesRulesetEndToken" + || $class === "CssAtPageEndToken" + || $class === "CssAtVariablesEndToken" + || $class === "CssRulesetEndToken" + ) + { + $r[] = $indent . "}"; + $level--; + } + } + return implode("\n", $r); + } + } + +/** + * This {@link aCssMinifierPlugin} will process var-statement and sets the declaration value to the variable value. + * + * This plugin only apply the variable values. The variable values itself will get parsed by the + * {@link CssVariablesMinifierFilter}. + * + * Example: + * + * @variables + * { + * defaultColor: black; + * } + * color: var(defaultColor); + * + * + * Will get converted to: + * + * color:black; + * + * + * @package CssMin/Minifier/Plugins + * @link http://code.google.com/p/cssmin/ + * @author Joe Scylla + * @copyright 2008 - 2011 Joe Scylla + * @license http://opensource.org/licenses/mit-license.php MIT License + * @version 3.0.1 + */ +class CssVariablesMinifierPlugin extends aCssMinifierPlugin + { + /** + * Regular expression matching a value. + * + * @var string + */ + private $reMatch = "/var\((.+)\)/iSU"; + /** + * Parsed variables. + * + * @var array + */ + private $variables = null; + /** + * Returns the variables. + * + * @return array + */ + public function getVariables() + { + return $this->variables; + } + /** + * Implements {@link aCssMinifierPlugin::minify()}. + * + * @param aCssToken $token Token to process + * @return boolean Return TRUE to break the processing of this token; FALSE to continue + */ + public function apply(aCssToken &$token) + { + if (stripos($token->Value, "var") !== false && preg_match_all($this->reMatch, $token->Value, $m)) + { + $mediaTypes = $token->MediaTypes; + if (!in_array("all", $mediaTypes)) + { + $mediaTypes[] = "all"; + } + for ($i = 0, $l = count($m[0]); $i < $l; $i++) + { + $variable = trim($m[1][$i]); + foreach ($mediaTypes as $mediaType) + { + if (isset($this->variables[$mediaType], $this->variables[$mediaType][$variable])) + { + // Variable value found => set the declaration value to the variable value and return + $token->Value = str_replace($m[0][$i], $this->variables[$mediaType][$variable], $token->Value); + continue 2; + } + } + // If no value was found trigger an error and replace the token with a CssNullToken + CssMin::triggerError(new CssError(__FILE__, __LINE__, __METHOD__ . ": No value found for variable " . $variable . " in media types " . implode(", ", $mediaTypes) . "", (string) $token)); + $token = new CssNullToken(); + return true; + } + } + return false; + } + /** + * Implements {@link aMinifierPlugin::getTriggerTokens()} + * + * @return array + */ + public function getTriggerTokens() + { + return array + ( + "CssAtFontFaceDeclarationToken", + "CssAtPageDeclarationToken", + "CssRulesetDeclarationToken" + ); + } + /** + * Sets the variables. + * + * @param array $variables Variables to set + * @return void + */ + public function setVariables(array $variables) + { + $this->variables = $variables; + } + } + +/** + * This {@link aCssMinifierFilter minifier filter} will parse the variable declarations out of @variables at-rule + * blocks. The variables will get store in the {@link CssVariablesMinifierPlugin} that will apply the variables to + * declaration. + * + * @package CssMin/Minifier/Filters + * @link http://code.google.com/p/cssmin/ + * @author Joe Scylla + * @copyright 2008 - 2011 Joe Scylla + * @license http://opensource.org/licenses/mit-license.php MIT License + * @version 3.0.1 + */ +class CssVariablesMinifierFilter extends aCssMinifierFilter + { + /** + * Implements {@link aCssMinifierFilter::filter()}. + * + * @param array $tokens Array of objects of type aCssToken + * @return integer Count of added, changed or removed tokens; a return value large than 0 will rebuild the array + */ + public function apply(array &$tokens) + { + $variables = array(); + $defaultMediaTypes = array("all"); + $mediaTypes = array(); + $remove = array(); + for($i = 0, $l = count($tokens); $i < $l; $i++) + { + // @variables at-rule block found + if (get_class($tokens[$i]) === "CssAtVariablesStartToken") + { + $remove[] = $i; + $mediaTypes = (count($tokens[$i]->MediaTypes) == 0 ? $defaultMediaTypes : $tokens[$i]->MediaTypes); + foreach ($mediaTypes as $mediaType) + { + if (!isset($variables[$mediaType])) + { + $variables[$mediaType] = array(); + } + } + // Read the variable declaration tokens + for($i = $i; $i < $l; $i++) + { + // Found a variable declaration => read the variable values + if (get_class($tokens[$i]) === "CssAtVariablesDeclarationToken") + { + foreach ($mediaTypes as $mediaType) + { + $variables[$mediaType][$tokens[$i]->Property] = $tokens[$i]->Value; + } + $remove[] = $i; + } + // Found the variables end token => break; + elseif (get_class($tokens[$i]) === "CssAtVariablesEndToken") + { + $remove[] = $i; + break; + } + } + } + } + // Variables in @variables at-rule blocks + foreach($variables as $mediaType => $null) + { + foreach($variables[$mediaType] as $variable => $value) + { + // If a var() statement in a variable value found... + if (stripos($value, "var") !== false && preg_match_all("/var\((.+)\)/iSU", $value, $m)) + { + // ... then replace the var() statement with the variable values. + for ($i = 0, $l = count($m[0]); $i < $l; $i++) + { + $variables[$mediaType][$variable] = str_replace($m[0][$i], (isset($variables[$mediaType][$m[1][$i]]) ? $variables[$mediaType][$m[1][$i]] : ""), $variables[$mediaType][$variable]); + } + } + } + } + // Remove the complete @variables at-rule block + foreach ($remove as $i) + { + $tokens[$i] = null; + } + if (!($plugin = $this->minifier->getPlugin("CssVariablesMinifierPlugin"))) + { + CssMin::triggerError(new CssError(__FILE__, __LINE__, __METHOD__ . ": The plugin CssVariablesMinifierPlugin was not found but is required for " . __CLASS__ . "")); + } + else + { + $plugin->setVariables($variables); + } + return count($remove); + } + } + +/** + * {@link aCssParserPlugin Parser plugin} for preserve parsing url() values. + * + * This plugin return no {@link aCssToken CssToken} but ensures that url() values will get parsed properly. + * + * @package CssMin/Parser/Plugins + * @link http://code.google.com/p/cssmin/ + * @author Joe Scylla + * @copyright 2008 - 2011 Joe Scylla + * @license http://opensource.org/licenses/mit-license.php MIT License + * @version 3.0.1 + */ +class CssUrlParserPlugin extends aCssParserPlugin + { + /** + * Implements {@link aCssParserPlugin::getTriggerChars()}. + * + * @return array + */ + public function getTriggerChars() + { + return array("(", ")"); + } + /** + * Implements {@link aCssParserPlugin::getTriggerStates()}. + * + * @return array + */ + public function getTriggerStates() + { + return false; + } + /** + * Implements {@link aCssParserPlugin::parse()}. + * + * @param integer $index Current index + * @param string $char Current char + * @param string $previousChar Previous char + * @return mixed TRUE will break the processing; FALSE continue with the next plugin; integer set a new index and break the processing + */ + public function parse($index, $char, $previousChar, $state) + { + // Start of string + if ($char === "(" && strtolower(substr($this->parser->getSource(), $index - 3, 4)) === "url(" && $state !== "T_URL") + { + $this->parser->pushState("T_URL"); + $this->parser->setExclusive(__CLASS__); + } + // Escaped LF in url => remove escape backslash and LF + elseif ($char === "\n" && $previousChar === "\\" && $state === "T_URL") + { + $this->parser->setBuffer(substr($this->parser->getBuffer(), 0, -2)); + } + // Parse error: Unescaped LF in string literal + elseif ($char === "\n" && $previousChar !== "\\" && $state === "T_URL") + { + $line = $this->parser->getBuffer(); + $this->parser->setBuffer(substr($this->parser->getBuffer(), 0, -1) . ")"); // Replace the LF with the url string delimiter + $this->parser->popState(); + $this->parser->unsetExclusive(); + CssMin::triggerError(new CssError(__FILE__, __LINE__, __METHOD__ . ": Unterminated string literal", $line . "_")); + } + // End of string + elseif ($char === ")" && $state === "T_URL") + { + $this->parser->popState(); + $this->parser->unsetExclusive(); + } + else + { + return false; + } + return true; + } + } + +/** + * {@link aCssParserPlugin Parser plugin} for preserve parsing string values. + * + * This plugin return no {@link aCssToken CssToken} but ensures that string values will get parsed properly. + * + * @package CssMin/Parser/Plugins + * @link http://code.google.com/p/cssmin/ + * @author Joe Scylla + * @copyright 2008 - 2011 Joe Scylla + * @license http://opensource.org/licenses/mit-license.php MIT License + * @version 3.0.1 + */ +class CssStringParserPlugin extends aCssParserPlugin + { + /** + * Current string delimiter char. + * + * @var string + */ + private $delimiterChar = null; + /** + * Implements {@link aCssParserPlugin::getTriggerChars()}. + * + * @return array + */ + public function getTriggerChars() + { + return array("\"", "'", "\n"); + } + /** + * Implements {@link aCssParserPlugin::getTriggerStates()}. + * + * @return array + */ + public function getTriggerStates() + { + return false; + } + /** + * Implements {@link aCssParserPlugin::parse()}. + * + * @param integer $index Current index + * @param string $char Current char + * @param string $previousChar Previous char + * @return mixed TRUE will break the processing; FALSE continue with the next plugin; integer set a new index and break the processing + */ + public function parse($index, $char, $previousChar, $state) + { + // Start of string + if (($char === "\"" || $char === "'") && $state !== "T_STRING") + { + $this->delimiterChar = $char; + $this->parser->pushState("T_STRING"); + $this->parser->setExclusive(__CLASS__); + } + // Escaped LF in string => remove escape backslash and LF + elseif ($char === "\n" && $previousChar === "\\" && $state === "T_STRING") + { + $this->parser->setBuffer(substr($this->parser->getBuffer(), 0, -2)); + } + // Parse error: Unescaped LF in string literal + elseif ($char === "\n" && $previousChar !== "\\" && $state === "T_STRING") + { + $line = $this->parser->getBuffer(); + $this->parser->popState(); + $this->parser->unsetExclusive(); + $this->parser->setBuffer(substr($this->parser->getBuffer(), 0, -1) . $this->delimiterChar); // Replace the LF with the current string char + CssMin::triggerError(new CssError(__FILE__, __LINE__, __METHOD__ . ": Unterminated string literal", $line . "_")); + $this->delimiterChar = null; + } + // End of string + elseif ($char === $this->delimiterChar && $state === "T_STRING") + { + // If the Previous char is a escape char count the amount of the previous escape chars. If the amount of + // escape chars is uneven do not end the string + if ($previousChar == "\\") + { + $source = $this->parser->getSource(); + $c = 1; + $i = $index - 2; + while (substr($source, $i, 1) === "\\") + { + $c++; $i--; + } + if ($c % 2) + { + return false; + } + } + $this->parser->popState(); + $this->parser->unsetExclusive(); + $this->delimiterChar = null; + } + else + { + return false; + } + return true; + } + } + +/** + * This {@link aCssMinifierFilter minifier filter} sorts the ruleset declarations of a ruleset by name. + * + * @package CssMin/Minifier/Filters + * @link http://code.google.com/p/cssmin/ + * @author Rowan Beentje + * @copyright Rowan Beentje + * @license http://opensource.org/licenses/mit-license.php MIT License + * @version 3.0.1 + */ +class CssSortRulesetPropertiesMinifierFilter extends aCssMinifierFilter + { + /** + * Implements {@link aCssMinifierFilter::filter()}. + * + * @param array $tokens Array of objects of type aCssToken + * @return integer Count of added, changed or removed tokens; a return value larger than 0 will rebuild the array + */ + public function apply(array &$tokens) + { + $r = 0; + for ($i = 0, $l = count($tokens); $i < $l; $i++) + { + // Only look for ruleset start rules + if (get_class($tokens[$i]) !== "CssRulesetStartToken") { continue; } + // Look for the corresponding ruleset end + $endIndex = false; + for ($ii = $i + 1; $ii < $l; $ii++) + { + if (get_class($tokens[$ii]) !== "CssRulesetEndToken") { continue; } + $endIndex = $ii; + break; + } + if (!$endIndex) { break; } + $startIndex = $i; + $i = $endIndex; + // Skip if there's only one token in this ruleset + if ($endIndex - $startIndex <= 2) { continue; } + // Ensure that everything between the start and end is a declaration token, for safety + for ($ii = $startIndex + 1; $ii < $endIndex; $ii++) + { + if (get_class($tokens[$ii]) !== "CssRulesetDeclarationToken") { continue(2); } + } + $declarations = array_slice($tokens, $startIndex + 1, $endIndex - $startIndex - 1); + // Check whether a sort is required + $sortRequired = $lastPropertyName = false; + foreach ($declarations as $declaration) + { + if ($lastPropertyName) + { + if (strcmp($lastPropertyName, $declaration->Property) > 0) + { + $sortRequired = true; + break; + } + } + $lastPropertyName = $declaration->Property; + } + if (!$sortRequired) { continue; } + // Arrange the declarations alphabetically by name + usort($declarations, array(__CLASS__, "userDefinedSort1")); + // Update "IsLast" property + for ($ii = 0, $ll = count($declarations) - 1; $ii <= $ll; $ii++) + { + if ($ii == $ll) + { + $declarations[$ii]->IsLast = true; + } + else + { + $declarations[$ii]->IsLast = false; + } + } + // Splice back into the array. + array_splice($tokens, $startIndex + 1, $endIndex - $startIndex - 1, $declarations); + $r += $endIndex - $startIndex - 1; + } + return $r; + } + /** + * User defined sort function. + * + * @return integer + */ + public static function userDefinedSort1($a, $b) + { + return strcmp($a->Property, $b->Property); + } + } + +/** + * This {@link aCssToken CSS token} represents the start of a ruleset. + * + * @package CssMin/Tokens + * @link http://code.google.com/p/cssmin/ + * @author Joe Scylla + * @copyright 2008 - 2011 Joe Scylla + * @license http://opensource.org/licenses/mit-license.php MIT License + * @version 3.0.1 + */ +class CssRulesetStartToken extends aCssRulesetStartToken + { + /** + * Array of selectors. + * + * @var array + */ + public $Selectors = array(); + /** + * Set the properties of a ruleset token. + * + * @param array $selectors Selectors of the ruleset + * @return void + */ + public function __construct(array $selectors = array()) + { + $this->Selectors = $selectors; + } + /** + * Implements {@link aCssToken::__toString()}. + * + * @return string + */ + public function __toString() + { + return implode(",", $this->Selectors) . "{"; + } + } + +/** + * {@link aCssParserPlugin Parser plugin} for parsing ruleset block with including declarations. + * + * Found rulesets will add a {@link CssRulesetStartToken} and {@link CssRulesetEndToken} to the + * parser; including declarations as {@link CssRulesetDeclarationToken}. + * + * @package CssMin/Parser/Plugins + * @link http://code.google.com/p/cssmin/ + * @author Joe Scylla + * @copyright 2008 - 2011 Joe Scylla + * @license http://opensource.org/licenses/mit-license.php MIT License + * @version 3.0.1 + */ +class CssRulesetParserPlugin extends aCssParserPlugin + { + /** + * Implements {@link aCssParserPlugin::getTriggerChars()}. + * + * @return array + */ + public function getTriggerChars() + { + return array(",", "{", "}", ":", ";"); + } + /** + * Implements {@link aCssParserPlugin::getTriggerStates()}. + * + * @return array + */ + public function getTriggerStates() + { + return array("T_DOCUMENT", "T_AT_MEDIA", "T_RULESET::SELECTORS", "T_RULESET", "T_RULESET_DECLARATION"); + } + /** + * Selectors. + * + * @var array + */ + private $selectors = array(); + /** + * Implements {@link aCssParserPlugin::parse()}. + * + * @param integer $index Current index + * @param string $char Current char + * @param string $previousChar Previous char + * @return mixed TRUE will break the processing; FALSE continue with the next plugin; integer set a new index and break the processing + */ + public function parse($index, $char, $previousChar, $state) + { + // Start of Ruleset and selectors + if ($char === "," && ($state === "T_DOCUMENT" || $state === "T_AT_MEDIA" || $state === "T_RULESET::SELECTORS")) + { + if ($state !== "T_RULESET::SELECTORS") + { + $this->parser->pushState("T_RULESET::SELECTORS"); + } + $this->selectors[] = $this->parser->getAndClearBuffer(",{"); + } + // End of selectors and start of declarations + elseif ($char === "{" && ($state === "T_DOCUMENT" || $state === "T_AT_MEDIA" || $state === "T_RULESET::SELECTORS")) + { + if ($this->parser->getBuffer() !== "") + { + $this->selectors[] = $this->parser->getAndClearBuffer(",{"); + if ($state == "T_RULESET::SELECTORS") + { + $this->parser->popState(); + } + $this->parser->pushState("T_RULESET"); + $this->parser->appendToken(new CssRulesetStartToken($this->selectors)); + $this->selectors = array(); + } + } + // Start of declaration + elseif ($char === ":" && $state === "T_RULESET") + { + $this->parser->pushState("T_RULESET_DECLARATION"); + $this->buffer = $this->parser->getAndClearBuffer(":;", true); + } + // Unterminated ruleset declaration + elseif ($char === ":" && $state === "T_RULESET_DECLARATION") + { + // Ignore Internet Explorer filter declarations + if ($this->buffer === "filter") + { + return false; + } + CssMin::triggerError(new CssError(__FILE__, __LINE__, __METHOD__ . ": Unterminated declaration", $this->buffer . ":" . $this->parser->getBuffer() . "_")); + } + // End of declaration + elseif (($char === ";" || $char === "}") && $state === "T_RULESET_DECLARATION") + { + $value = $this->parser->getAndClearBuffer(";}"); + if (strtolower(substr($value, -10, 10)) === "!important") + { + $value = trim(substr($value, 0, -10)); + $isImportant = true; + } + else + { + $isImportant = false; + } + $this->parser->popState(); + $this->parser->appendToken(new CssRulesetDeclarationToken($this->buffer, $value, $this->parser->getMediaTypes(), $isImportant)); + // Declaration ends with a right curly brace; so we have to end the ruleset + if ($char === "}") + { + $this->parser->appendToken(new CssRulesetEndToken()); + $this->parser->popState(); + } + $this->buffer = ""; + } + // End of ruleset + elseif ($char === "}" && $state === "T_RULESET") + { + $this->parser->popState(); + $this->parser->clearBuffer(); + $this->parser->appendToken(new CssRulesetEndToken()); + $this->buffer = ""; + $this->selectors = array(); + } + else + { + return false; + } + return true; + } + } + +/** + * This {@link aCssToken CSS token} represents the end of a ruleset. + * + * @package CssMin/Tokens + * @link http://code.google.com/p/cssmin/ + * @author Joe Scylla + * @copyright 2008 - 2011 Joe Scylla + * @license http://opensource.org/licenses/mit-license.php MIT License + * @version 3.0.1 + */ +class CssRulesetEndToken extends aCssRulesetEndToken + { + + } + +/** + * This {@link aCssToken CSS token} represents a ruleset declaration. + * + * @package CssMin/Tokens + * @link http://code.google.com/p/cssmin/ + * @author Joe Scylla + * @copyright 2008 - 2011 Joe Scylla + * @license http://opensource.org/licenses/mit-license.php MIT License + * @version 3.0.1 + */ +class CssRulesetDeclarationToken extends aCssDeclarationToken + { + /** + * Media types of the declaration. + * + * @var array + */ + public $MediaTypes = array("all"); + /** + * Set the properties of a ddocument- or at-rule @media level declaration. + * + * @param string $property Property of the declaration + * @param string $value Value of the declaration + * @param mixed $mediaTypes Media types of the declaration + * @param boolean $isImportant Is the !important flag is set + * @param boolean $isLast Is the declaration the last one of the ruleset + * @return void + */ + public function __construct($property, $value, $mediaTypes = null, $isImportant = false, $isLast = false) + { + parent::__construct($property, $value, $isImportant, $isLast); + $this->MediaTypes = $mediaTypes ? $mediaTypes : array("all"); + } + } + +/** + * This {@link aCssMinifierFilter minifier filter} sets the IsLast property of any last declaration in a ruleset, + * @font-face at-rule or @page at-rule block. If the property IsLast is TRUE the decrations will get stringified + * without tailing semicolon. + * + * @package CssMin/Minifier/Filters + * @link http://code.google.com/p/cssmin/ + * @author Joe Scylla + * @copyright 2008 - 2011 Joe Scylla + * @license http://opensource.org/licenses/mit-license.php MIT License + * @version 3.0.1 + */ +class CssRemoveLastDelarationSemiColonMinifierFilter extends aCssMinifierFilter + { + /** + * Implements {@link aCssMinifierFilter::filter()}. + * + * @param array $tokens Array of objects of type aCssToken + * @return integer Count of added, changed or removed tokens; a return value large than 0 will rebuild the array + */ + public function apply(array &$tokens) + { + for ($i = 0, $l = count($tokens); $i < $l; $i++) + { + $current = get_class($tokens[$i]); + $next = isset($tokens[$i+1]) ? get_class($tokens[$i+1]) : false; + if (($current === "CssRulesetDeclarationToken" && $next === "CssRulesetEndToken") || + ($current === "CssAtFontFaceDeclarationToken" && $next === "CssAtFontFaceEndToken") || + ($current === "CssAtPageDeclarationToken" && $next === "CssAtPageEndToken")) + { + $tokens[$i]->IsLast = true; + } + } + return 0; + } + } + +/** + * This {@link aCssMinifierFilter minifier filter} will remove any empty rulesets (including @keyframes at-rule block + * rulesets). + * + * @package CssMin/Minifier/Filters + * @link http://code.google.com/p/cssmin/ + * @author Joe Scylla + * @copyright 2008 - 2011 Joe Scylla + * @license http://opensource.org/licenses/mit-license.php MIT License + * @version 3.0.1 + */ +class CssRemoveEmptyRulesetsMinifierFilter extends aCssMinifierFilter + { + /** + * Implements {@link aCssMinifierFilter::filter()}. + * + * @param array $tokens Array of objects of type aCssToken + * @return integer Count of added, changed or removed tokens; a return value large than 0 will rebuild the array + */ + public function apply(array &$tokens) + { + $r = 0; + for ($i = 0, $l = count($tokens); $i < $l; $i++) + { + $current = get_class($tokens[$i]); + $next = isset($tokens[$i + 1]) ? get_class($tokens[$i + 1]) : false; + if (($current === "CssRulesetStartToken" && $next === "CssRulesetEndToken") || + ($current === "CssAtKeyframesRulesetStartToken" && $next === "CssAtKeyframesRulesetEndToken" && !array_intersect(array("from", "0%", "to", "100%"), array_map("strtolower", $tokens[$i]->Selectors))) + ) + { + $tokens[$i] = null; + $tokens[$i + 1] = null; + $i++; + $r = $r + 2; + } + } + return $r; + } + } + +/** + * This {@link aCssMinifierFilter minifier filter} will remove any empty @font-face, @keyframes, @media and @page + * at-rule blocks. + * + * @package CssMin/Minifier/Filters + * @link http://code.google.com/p/cssmin/ + * @author Joe Scylla + * @copyright 2008 - 2011 Joe Scylla + * @license http://opensource.org/licenses/mit-license.php MIT License + * @version 3.0.1 + */ +class CssRemoveEmptyAtBlocksMinifierFilter extends aCssMinifierFilter + { + /** + * Implements {@link aCssMinifierFilter::filter()}. + * + * @param array $tokens Array of objects of type aCssToken + * @return integer Count of added, changed or removed tokens; a return value large than 0 will rebuild the array + */ + public function apply(array &$tokens) + { + $r = 0; + for ($i = 0, $l = count($tokens); $i < $l; $i++) + { + $current = get_class($tokens[$i]); + $next = isset($tokens[$i + 1]) ? get_class($tokens[$i + 1]) : false; + if (($current === "CssAtFontFaceStartToken" && $next === "CssAtFontFaceEndToken") || + ($current === "CssAtKeyframesStartToken" && $next === "CssAtKeyframesEndToken") || + ($current === "CssAtPageStartToken" && $next === "CssAtPageEndToken") || + ($current === "CssAtMediaStartToken" && $next === "CssAtMediaEndToken")) + { + $tokens[$i] = null; + $tokens[$i + 1] = null; + $i++; + $r = $r + 2; + } + } + return $r; + } + } + +/** + * This {@link aCssMinifierFilter minifier filter} will remove any comments from the array of parsed tokens. + * + * @package CssMin/Minifier/Filters + * @link http://code.google.com/p/cssmin/ + * @author Joe Scylla + * @copyright 2008 - 2011 Joe Scylla + * @license http://opensource.org/licenses/mit-license.php MIT License + * @version 3.0.1 + */ +class CssRemoveCommentsMinifierFilter extends aCssMinifierFilter + { + /** + * Implements {@link aCssMinifierFilter::filter()}. + * + * @param array $tokens Array of objects of type aCssToken + * @return integer Count of added, changed or removed tokens; a return value large than 0 will rebuild the array + */ + public function apply(array &$tokens) + { + $r = 0; + for ($i = 0, $l = count($tokens); $i < $l; $i++) + { + if (get_class($tokens[$i]) === "CssCommentToken") + { + $tokens[$i] = null; + $r++; + } + } + return $r; + } + } + +/** + * CSS Parser. + * + * @package CssMin/Parser + * @link http://code.google.com/p/cssmin/ + * @author Joe Scylla + * @copyright 2008 - 2011 Joe Scylla + * @license http://opensource.org/licenses/mit-license.php MIT License + * @version 3.0.1 + */ +class CssParser + { + /** + * Parse buffer. + * + * @var string + */ + private $buffer = ""; + /** + * {@link aCssParserPlugin Plugins}. + * + * @var array + */ + private $plugins = array(); + /** + * Source to parse. + * + * @var string + */ + private $source = ""; + /** + * Current state. + * + * @var integer + */ + private $state = "T_DOCUMENT"; + /** + * Exclusive state. + * + * @var string + */ + private $stateExclusive = false; + /** + * Media types state. + * + * @var mixed + */ + private $stateMediaTypes = false; + /** + * State stack. + * + * @var array + */ + private $states = array("T_DOCUMENT"); + /** + * Parsed tokens. + * + * @var array + */ + private $tokens = array(); + /** + * Constructer. + * + * Create instances of the used {@link aCssParserPlugin plugins}. + * + * @param string $source CSS source [optional] + * @param array $plugins Plugin configuration [optional] + * @return void + */ + public function __construct($source = null, array $plugins = null) + { + $plugins = array_merge(array + ( + "Comment" => true, + "String" => true, + "Url" => true, + "Expression" => true, + "Ruleset" => true, + "AtCharset" => true, + "AtFontFace" => true, + "AtImport" => true, + "AtKeyframes" => true, + "AtMedia" => true, + "AtPage" => true, + "AtVariables" => true + ), is_array($plugins) ? $plugins : array()); + // Create plugin instances + foreach ($plugins as $name => $config) + { + if ($config !== false) + { + $class = "Css" . $name . "ParserPlugin"; + $config = is_array($config) ? $config : array(); + if (class_exists($class)) + { + $this->plugins[] = new $class($this, $config); + } + else + { + CssMin::triggerError(new CssError(__FILE__, __LINE__, __METHOD__ . ": The plugin " . $name . " with the class name " . $class . " was not found")); + } + } + } + if (!is_null($source)) + { + $this->parse($source); + } + } + /** + * Append a token to the array of tokens. + * + * @param aCssToken $token Token to append + * @return void + */ + public function appendToken(aCssToken $token) + { + $this->tokens[] = $token; + } + /** + * Clears the current buffer. + * + * @return void + */ + public function clearBuffer() + { + $this->buffer = ""; + } + /** + * Returns and clear the current buffer. + * + * @param string $trim Chars to use to trim the returned buffer + * @param boolean $tolower if TRUE the returned buffer will get converted to lower case + * @return string + */ + public function getAndClearBuffer($trim = "", $tolower = false) + { + $r = $this->getBuffer($trim, $tolower); + $this->buffer = ""; + return $r; + } + /** + * Returns the current buffer. + * + * @param string $trim Chars to use to trim the returned buffer + * @param boolean $tolower if TRUE the returned buffer will get converted to lower case + * @return string + */ + public function getBuffer($trim = "", $tolower = false) + { + $r = $this->buffer; + if ($trim) + { + $r = trim($r, " \t\n\r\0\x0B" . $trim); + } + if ($tolower) + { + $r = strtolower($r); + } + return $r; + } + /** + * Returns the current media types state. + * + * @return array + */ + public function getMediaTypes() + { + return $this->stateMediaTypes; + } + /** + * Returns the CSS source. + * + * @return string + */ + public function getSource() + { + return $this->source; + } + /** + * Returns the current state. + * + * @return integer The current state + */ + public function getState() + { + return $this->state; + } + /** + * Returns a plugin by class name. + * + * @param string $name Class name of the plugin + * @return aCssParserPlugin + */ + public function getPlugin($class) + { + static $index = null; + if (is_null($index)) + { + $index = array(); + for ($i = 0, $l = count($this->plugins); $i < $l; $i++) + { + $index[get_class($this->plugins[$i])] = $i; + } + } + return isset($index[$class]) ? $this->plugins[$index[$class]] : false; + } + /** + * Returns the parsed tokens. + * + * @return array + */ + public function getTokens() + { + return $this->tokens; + } + /** + * Returns if the current state equals the passed state. + * + * @param integer $state State to compare with the current state + * @return boolean TRUE is the state equals to the passed state; FALSE if not + */ + public function isState($state) + { + return ($this->state == $state); + } + /** + * Parse the CSS source and return a array with parsed tokens. + * + * @param string $source CSS source + * @return array Array with tokens + */ + public function parse($source) + { + // Reset + $this->source = ""; + $this->tokens = array(); + // Create a global and plugin lookup table for trigger chars; set array of plugins as local variable and create + // several helper variables for plugin handling + $globalTriggerChars = ""; + $plugins = $this->plugins; + $pluginCount = count($plugins); + $pluginIndex = array(); + $pluginTriggerStates = array(); + $pluginTriggerChars = array(); + for ($i = 0, $l = count($plugins); $i < $l; $i++) + { + $tPluginClassName = get_class($plugins[$i]); + $pluginTriggerChars[$i] = implode("", $plugins[$i]->getTriggerChars()); + $tPluginTriggerStates = $plugins[$i]->getTriggerStates(); + $pluginTriggerStates[$i] = $tPluginTriggerStates === false ? false : "|" . implode("|", $tPluginTriggerStates) . "|"; + $pluginIndex[$tPluginClassName] = $i; + for ($ii = 0, $ll = strlen($pluginTriggerChars[$i]); $ii < $ll; $ii++) + { + $c = substr($pluginTriggerChars[$i], $ii, 1); + if (strpos($globalTriggerChars, $c) === false) + { + $globalTriggerChars .= $c; + } + } + } + // Normalise line endings + $source = str_replace("\r\n", "\n", $source); // Windows to Unix line endings + $source = str_replace("\r", "\n", $source); // Mac to Unix line endings + $this->source = $source; + // Variables + $buffer = &$this->buffer; + $exclusive = &$this->stateExclusive; + $state = &$this->state; + $c = $p = null; + // -- + for ($i = 0, $l = strlen($source); $i < $l; $i++) + { + // Set the current Char + $c = $source[$i]; // Is faster than: $c = substr($source, $i, 1); + // Normalize and filter double whitespace characters + if ($exclusive === false) + { + if ($c === "\n" || $c === "\t") + { + $c = " "; + } + if ($c === " " && $p === " ") + { + continue; + } + } + $buffer .= $c; + // Extended processing only if the current char is a global trigger char + if (strpos($globalTriggerChars, $c) !== false) + { + // Exclusive state is set; process with the exclusive plugin + if ($exclusive) + { + $tPluginIndex = $pluginIndex[$exclusive]; + if (strpos($pluginTriggerChars[$tPluginIndex], $c) !== false && ($pluginTriggerStates[$tPluginIndex] === false || strpos($pluginTriggerStates[$tPluginIndex], $state) !== false)) + { + $r = $plugins[$tPluginIndex]->parse($i, $c, $p, $state); + // Return value is TRUE => continue with next char + if ($r === true) + { + continue; + } + // Return value is numeric => set new index and continue with next char + elseif ($r !== false && $r != $i) + { + $i = $r; + continue; + } + } + } + // Else iterate through the plugins + else + { + $triggerState = "|" . $state . "|"; + for ($ii = 0, $ll = $pluginCount; $ii < $ll; $ii++) + { + // Only process if the current char is one of the plugin trigger chars + if (strpos($pluginTriggerChars[$ii], $c) !== false && ($pluginTriggerStates[$ii] === false || strpos($pluginTriggerStates[$ii], $triggerState) !== false)) + { + // Process with the plugin + $r = $plugins[$ii]->parse($i, $c, $p, $state); + // Return value is TRUE => break the plugin loop and and continue with next char + if ($r === true) + { + break; + } + // Return value is numeric => set new index, break the plugin loop and and continue with next char + elseif ($r !== false && $r != $i) + { + $i = $r; + break; + } + } + } + } + } + $p = $c; // Set the parent char + } + return $this->tokens; + } + /** + * Remove the last state of the state stack and return the removed stack value. + * + * @return integer Removed state value + */ + public function popState() + { + $r = array_pop($this->states); + $this->state = $this->states[count($this->states) - 1]; + return $r; + } + /** + * Adds a new state onto the state stack. + * + * @param integer $state State to add onto the state stack. + * @return integer The index of the added state in the state stacks + */ + public function pushState($state) + { + $r = array_push($this->states, $state); + $this->state = $this->states[count($this->states) - 1]; + return $r; + } + /** + * Sets/restores the buffer. + * + * @param string $buffer Buffer to set + * @return void + */ + public function setBuffer($buffer) + { + $this->buffer = $buffer; + } + /** + * Set the exclusive state. + * + * @param string $exclusive Exclusive state + * @return void + */ + public function setExclusive($exclusive) + { + $this->stateExclusive = $exclusive; + } + /** + * Set the media types state. + * + * @param array $mediaTypes Media types state + * @return void + */ + public function setMediaTypes(array $mediaTypes) + { + $this->stateMediaTypes = $mediaTypes; + } + /** + * Sets the current state in the state stack; equals to {@link CssParser::popState()} + {@link CssParser::pushState()}. + * + * @param integer $state State to set + * @return integer + */ + public function setState($state) + { + $r = array_pop($this->states); + array_push($this->states, $state); + $this->state = $this->states[count($this->states) - 1]; + return $r; + } + /** + * Removes the exclusive state. + * + * @return void + */ + public function unsetExclusive() + { + $this->stateExclusive = false; + } + /** + * Removes the media types state. + * + * @return void + */ + public function unsetMediaTypes() + { + $this->stateMediaTypes = false; + } + } + +/** + * {@link aCssFromatter Formatter} returning the CSS source in {@link http://goo.gl/j4XdU OTBS indent style} (The One True Brace Style). + * + * @package CssMin/Formatter + * @link http://code.google.com/p/cssmin/ + * @author Joe Scylla + * @copyright 2008 - 2011 Joe Scylla + * @license http://opensource.org/licenses/mit-license.php MIT License + * @version 3.0.1 + */ +class CssOtbsFormatter extends aCssFormatter + { + /** + * Implements {@link aCssFormatter::__toString()}. + * + * @return string + */ + public function __toString() + { + $r = array(); + $level = 0; + for ($i = 0, $l = count($this->tokens); $i < $l; $i++) + { + $token = $this->tokens[$i]; + $class = get_class($token); + $indent = str_repeat($this->indent, $level); + if ($class === "CssCommentToken") + { + $lines = array_map("trim", explode("\n", $token->Comment)); + for ($ii = 0, $ll = count($lines); $ii < $ll; $ii++) + { + $r[] = $indent . (substr($lines[$ii], 0, 1) == "*" ? " " : "") . $lines[$ii]; + } + } + elseif ($class === "CssAtCharsetToken") + { + $r[] = $indent . "@charset " . $token->Charset . ";"; + } + elseif ($class === "CssAtFontFaceStartToken") + { + $r[] = $indent . "@font-face {"; + $level++; + } + elseif ($class === "CssAtImportToken") + { + $r[] = $indent . "@import " . $token->Import . " " . implode(", ", $token->MediaTypes) . ";"; + } + elseif ($class === "CssAtKeyframesStartToken") + { + $r[] = $indent . "@keyframes \"" . $token->Name . "\" {"; + $level++; + } + elseif ($class === "CssAtMediaStartToken") + { + $r[] = $indent . "@media " . implode(", ", $token->MediaTypes) . " {"; + $level++; + } + elseif ($class === "CssAtPageStartToken") + { + $r[] = $indent . "@page {"; + $level++; + } + elseif ($class === "CssAtVariablesStartToken") + { + $r[] = $indent . "@variables " . implode(", ", $token->MediaTypes) . " {"; + $level++; + } + elseif ($class === "CssRulesetStartToken" || $class === "CssAtKeyframesRulesetStartToken") + { + $r[] = $indent . implode(", ", $token->Selectors) . " {"; + $level++; + } + elseif ($class == "CssAtFontFaceDeclarationToken" + || $class === "CssAtKeyframesRulesetDeclarationToken" + || $class === "CssAtPageDeclarationToken" + || $class == "CssAtVariablesDeclarationToken" + || $class === "CssRulesetDeclarationToken" + ) + { + $declaration = $indent . $token->Property . ": "; + if ($this->padding) + { + $declaration = str_pad($declaration, $this->padding, " ", STR_PAD_RIGHT); + } + $r[] = $declaration . $token->Value . ($token->IsImportant ? " !important" : "") . ";"; + } + elseif ($class === "CssAtFontFaceEndToken" + || $class === "CssAtMediaEndToken" + || $class === "CssAtKeyframesEndToken" + || $class === "CssAtKeyframesRulesetEndToken" + || $class === "CssAtPageEndToken" + || $class === "CssAtVariablesEndToken" + || $class === "CssRulesetEndToken" + ) + { + $level--; + $r[] = str_repeat($indent, $level) . "}"; + } + } + return implode("\n", $r); + } + } + +/** + * This {@link aCssToken CSS token} is a utility token that extends {@link aNullToken} and returns only a empty string. + * + * @package CssMin/Tokens + * @link http://code.google.com/p/cssmin/ + * @author Joe Scylla + * @copyright 2008 - 2011 Joe Scylla + * @license http://opensource.org/licenses/mit-license.php MIT License + * @version 3.0.1 + */ +class CssNullToken extends aCssToken + { + /** + * Implements {@link aCssToken::__toString()}. + * + * @return string + */ + public function __toString() + { + return ""; + } + } + +/** + * CSS Minifier. + * + * @package CssMin/Minifier + * @link http://code.google.com/p/cssmin/ + * @author Joe Scylla + * @copyright 2008 - 2011 Joe Scylla + * @license http://opensource.org/licenses/mit-license.php MIT License + * @version 3.0.1 + */ +class CssMinifier + { + /** + * {@link aCssMinifierFilter Filters}. + * + * @var array + */ + private $filters = array(); + /** + * {@link aCssMinifierPlugin Plugins}. + * + * @var array + */ + private $plugins = array(); + /** + * Minified source. + * + * @var string + */ + private $minified = ""; + /** + * Constructer. + * + * Creates instances of {@link aCssMinifierFilter filters} and {@link aCssMinifierPlugin plugins}. + * + * @param string $source CSS source [optional] + * @param array $filters Filter configuration [optional] + * @param array $plugins Plugin configuration [optional] + * @return void + */ + public function __construct($source = null, array $filters = null, array $plugins = null) + { + $filters = array_merge(array + ( + "ImportImports" => false, + "RemoveComments" => true, + "RemoveEmptyRulesets" => true, + "RemoveEmptyAtBlocks" => true, + "ConvertLevel3Properties" => false, + "ConvertLevel3AtKeyframes" => false, + "Variables" => true, + "RemoveLastDelarationSemiColon" => true + ), is_array($filters) ? $filters : array()); + $plugins = array_merge(array + ( + "Variables" => true, + "ConvertFontWeight" => false, + "ConvertHslColors" => false, + "ConvertRgbColors" => false, + "ConvertNamedColors" => false, + "CompressColorValues" => false, + "CompressUnitValues" => false, + "CompressExpressionValues" => false + ), is_array($plugins) ? $plugins : array()); + // Filters + foreach ($filters as $name => $config) + { + if ($config !== false) + { + $class = "Css" . $name . "MinifierFilter"; + $config = is_array($config) ? $config : array(); + if (class_exists($class)) + { + $this->filters[] = new $class($this, $config); + } + else + { + CssMin::triggerError(new CssError(__FILE__, __LINE__, __METHOD__ . ": The filter " . $name . " with the class name " . $class . " was not found")); + } + } + } + // Plugins + foreach ($plugins as $name => $config) + { + if ($config !== false) + { + $class = "Css" . $name . "MinifierPlugin"; + $config = is_array($config) ? $config : array(); + if (class_exists($class)) + { + $this->plugins[] = new $class($this, $config); + } + else + { + CssMin::triggerError(new CssError(__FILE__, __LINE__, __METHOD__ . ": The plugin " . $name . " with the class name " . $class . " was not found")); + } + } + } + // -- + if (!is_null($source)) + { + $this->minify($source); + } + } + /** + * Returns the minified Source. + * + * @return string + */ + public function getMinified() + { + return $this->minified; + } + /** + * Returns a plugin by class name. + * + * @param string $name Class name of the plugin + * @return aCssMinifierPlugin + */ + public function getPlugin($class) + { + static $index = null; + if (is_null($index)) + { + $index = array(); + for ($i = 0, $l = count($this->plugins); $i < $l; $i++) + { + $index[get_class($this->plugins[$i])] = $i; + } + } + return isset($index[$class]) ? $this->plugins[$index[$class]] : false; + } + /** + * Minifies the CSS source. + * + * @param string $source CSS source + * @return string + */ + public function minify($source) + { + // Variables + $r = ""; + $parser = new CssParser($source); + $tokens = $parser->getTokens(); + $filters = $this->filters; + $filterCount = count($this->filters); + $plugins = $this->plugins; + $pluginCount = count($plugins); + $pluginIndex = array(); + $pluginTriggerTokens = array(); + $globalTriggerTokens = array(); + for ($i = 0, $l = count($plugins); $i < $l; $i++) + { + $tPluginClassName = get_class($plugins[$i]); + $pluginTriggerTokens[$i] = $plugins[$i]->getTriggerTokens(); + foreach ($pluginTriggerTokens[$i] as $v) + { + if (!in_array($v, $globalTriggerTokens)) + { + $globalTriggerTokens[] = $v; + } + } + $pluginTriggerTokens[$i] = "|" . implode("|", $pluginTriggerTokens[$i]) . "|"; + $pluginIndex[$tPluginClassName] = $i; + } + $globalTriggerTokens = "|" . implode("|", $globalTriggerTokens) . "|"; + /* + * Apply filters + */ + for($i = 0; $i < $filterCount; $i++) + { + // Apply the filter; if the return value is larger than 0... + if ($filters[$i]->apply($tokens) > 0) + { + // ...then filter null values and rebuild the token array + $tokens = array_values(array_filter($tokens)); + } + } + $tokenCount = count($tokens); + /* + * Apply plugins + */ + for($i = 0; $i < $tokenCount; $i++) + { + $triggerToken = "|" . get_class($tokens[$i]) . "|"; + if (strpos($globalTriggerTokens, $triggerToken) !== false) + { + for($ii = 0; $ii < $pluginCount; $ii++) + { + if (strpos($pluginTriggerTokens[$ii], $triggerToken) !== false || $pluginTriggerTokens[$ii] === false) + { + // Apply the plugin; if the return value is TRUE continue to the next token + if ($plugins[$ii]->apply($tokens[$i]) === true) + { + continue 2; + } + } + } + } + } + // Stringify the tokens + for($i = 0; $i < $tokenCount; $i++) + { + $r .= (string) $tokens[$i]; + } + $this->minified = $r; + return $r; + } + } + +/** + * CssMin - A (simple) css minifier with benefits + * + * -- + * Copyright (c) 2011 Joe Scylla + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN + * THE SOFTWARE. + * -- + * + * @package CssMin + * @link http://code.google.com/p/cssmin/ + * @author Joe Scylla + * @copyright 2008 - 2011 Joe Scylla + * @license http://opensource.org/licenses/mit-license.php MIT License + * @version 3.0.1 + */ +class CssMin + { + /** + * Index of classes + * + * @var array + */ + private static $classIndex = array(); + /** + * Parse/minify errors + * + * @var array + */ + private static $errors = array(); + /** + * Verbose output. + * + * @var boolean + */ + private static $isVerbose = false; + /** + * {@link http://goo.gl/JrW54 Autoload} function of CssMin. + * + * @param string $class Name of the class + * @return void + */ + public static function autoload($class) + { + if (isset(self::$classIndex[$class])) + { + require(self::$classIndex[$class]); + } + } + /** + * Return errors + * + * @return array of {CssError}. + */ + public static function getErrors() + { + return self::$errors; + } + /** + * Returns if there were errors. + * + * @return boolean + */ + public static function hasErrors() + { + return count(self::$errors) > 0; + } + /** + * Initialises CssMin. + * + * @return void + */ + public static function initialise() + { + // Create the class index for autoloading or including + $paths = array(dirname(__FILE__)); + //while (list($i, $path) = each($paths)) + do + { + $path = current($paths); + $subDirectorys = glob($path . "*", GLOB_MARK | GLOB_ONLYDIR | GLOB_NOSORT); + if (is_array($subDirectorys)) + { + foreach ($subDirectorys as $subDirectory) + { + $paths[] = $subDirectory; + } + } + $files = glob($path . "*.php", 0); + if (is_array($files)) + { + foreach ($files as $file) + { + $class = substr(basename($file), 0, -4); + self::$classIndex[$class] = $file; + } + } + } + while(next($paths)); + krsort(self::$classIndex); + // Only use autoloading if spl_autoload_register() is available and no __autoload() is defined (because + // __autoload() breaks if spl_autoload_register() is used. + if (function_exists("spl_autoload_register") && !is_callable("__autoload")) + { + spl_autoload_register(array(__CLASS__, "autoload")); + } + // Otherwise include all class files + else + { + foreach (self::$classIndex as $class => $file) + { + if (!class_exists($class)) + { + require_once($file); + } + } + } + } + /** + * Minifies CSS source. + * + * @param string $source CSS source + * @param array $filters Filter configuration [optional] + * @param array $plugins Plugin configuration [optional] + * @return string Minified CSS + */ + public static function minify($source, array $filters = null, array $plugins = null) + { + self::$errors = array(); + $minifier = new CssMinifier($source, $filters, $plugins); + return $minifier->getMinified(); + } + /** + * Parse the CSS source. + * + * @param string $source CSS source + * @param array $plugins Plugin configuration [optional] + * @return array Array of aCssToken + */ + public static function parse($source, array $plugins = null) + { + self::$errors = array(); + $parser = new CssParser($source, $plugins); + return $parser->getTokens(); + } + /** + * -- + * + * @param boolean $to + * @return boolean + */ + public static function setVerbose($to) + { + self::$isVerbose = (boolean) $to; + return self::$isVerbose; + } + /** + * -- + * + * @param CssError $error + * @return void + */ + public static function triggerError(CssError $error) + { + self::$errors[] = $error; + if (self::$isVerbose) + { + trigger_error((string) $error, E_USER_WARNING); + } + } + } +// Initialises CssMin +CssMin::initialise(); + +/** + * This {@link aCssMinifierFilter minifier filter} import external css files defined with the @import at-rule into the + * current stylesheet. + * + * @package CssMin/Minifier/Filters + * @link http://code.google.com/p/cssmin/ + * @author Joe Scylla + * @copyright 2008 - 2011 Joe Scylla + * @license http://opensource.org/licenses/mit-license.php MIT License + * @version 3.0.1 + */ +class CssImportImportsMinifierFilter extends aCssMinifierFilter + { + /** + * Array with already imported external stylesheets. + * + * @var array + */ + private $imported = array(); + /** + * Implements {@link aCssMinifierFilter::filter()}. + * + * @param array $tokens Array of objects of type aCssToken + * @return integer Count of added, changed or removed tokens; a return value large than 0 will rebuild the array + */ + public function apply(array &$tokens) + { + if (!isset($this->configuration["BasePath"]) || !is_dir($this->configuration["BasePath"])) + { + CssMin::triggerError(new CssError(__FILE__, __LINE__, __METHOD__ . ": Base path " . ($this->configuration["BasePath"] ? $this->configuration["BasePath"] : "null"). " is not a directory")); + return 0; + } + for ($i = 0, $l = count($tokens); $i < $l; $i++) + { + if (get_class($tokens[$i]) === "CssAtImportToken") + { + $import = $this->configuration["BasePath"] . "/" . $tokens[$i]->Import; + // Import file was not found/is not a file + if (!is_file($import)) + { + CssMin::triggerError(new CssError(__FILE__, __LINE__, __METHOD__ . ": Import file " . $import. " was not found.", (string) $tokens[$i])); + } + // Import file already imported; remove this @import at-rule to prevent recursions + elseif (in_array($import, $this->imported)) + { + CssMin::triggerError(new CssError(__FILE__, __LINE__, __METHOD__ . ": Import file " . $import. " was already imported.", (string) $tokens[$i])); + $tokens[$i] = null; + } + else + { + $this->imported[] = $import; + $parser = new CssParser(file_get_contents($import)); + $import = $parser->getTokens(); + // The @import at-rule has media types defined requiring special handling + if (count($tokens[$i]->MediaTypes) > 0 && !(count($tokens[$i]->MediaTypes) == 1 && $tokens[$i]->MediaTypes[0] == "all")) + { + $blocks = array(); + /* + * Filter or set media types of @import at-rule or remove the @import at-rule if no media type is matching the parent @import at-rule + */ + for($ii = 0, $ll = count($import); $ii < $ll; $ii++) + { + if (get_class($import[$ii]) === "CssAtImportToken") + { + // @import at-rule defines no media type or only the "all" media type; set the media types to the one defined in the parent @import at-rule + if (count($import[$ii]->MediaTypes) == 0 || (count($import[$ii]->MediaTypes) == 1 && $import[$ii]->MediaTypes[0] == "all")) + { + $import[$ii]->MediaTypes = $tokens[$i]->MediaTypes; + } + // @import at-rule defineds one or more media types; filter out media types not matching with the parent @import at-rule + elseif (count($import[$ii]->MediaTypes > 0)) + { + foreach ($import[$ii]->MediaTypes as $index => $mediaType) + { + if (!in_array($mediaType, $tokens[$i]->MediaTypes)) + { + unset($import[$ii]->MediaTypes[$index]); + } + } + $import[$ii]->MediaTypes = array_values($import[$ii]->MediaTypes); + // If there are no media types left in the @import at-rule remove the @import at-rule + if (count($import[$ii]->MediaTypes) == 0) + { + $import[$ii] = null; + } + } + } + } + /* + * Remove media types of @media at-rule block not defined in the @import at-rule + */ + for($ii = 0, $ll = count($import); $ii < $ll; $ii++) + { + if (get_class($import[$ii]) === "CssAtMediaStartToken") + { + foreach ($import[$ii]->MediaTypes as $index => $mediaType) + { + if (!in_array($mediaType, $tokens[$i]->MediaTypes)) + { + unset($import[$ii]->MediaTypes[$index]); + } + $import[$ii]->MediaTypes = array_values($import[$ii]->MediaTypes); + } + } + } + /* + * If no media types left of the @media at-rule block remove the complete block + */ + for($ii = 0, $ll = count($import); $ii < $ll; $ii++) + { + if (get_class($import[$ii]) === "CssAtMediaStartToken") + { + if (count($import[$ii]->MediaTypes) === 0) + { + for ($iii = $ii; $iii < $ll; $iii++) + { + if (get_class($import[$iii]) === "CssAtMediaEndToken") + { + break; + } + } + if (get_class($import[$iii]) === "CssAtMediaEndToken") + { + array_splice($import, $ii, $iii - $ii + 1, array()); + $ll = count($import); + } + } + } + } + /* + * If the media types of the @media at-rule equals the media types defined in the @import + * at-rule remove the CssAtMediaStartToken and CssAtMediaEndToken token + */ + for($ii = 0, $ll = count($import); $ii < $ll; $ii++) + { + if (get_class($import[$ii]) === "CssAtMediaStartToken" && count(array_diff($tokens[$i]->MediaTypes, $import[$ii]->MediaTypes)) === 0) + { + for ($iii = $ii; $iii < $ll; $iii++) + { + if (get_class($import[$iii]) == "CssAtMediaEndToken") + { + break; + } + } + if (get_class($import[$iii]) == "CssAtMediaEndToken") + { + unset($import[$ii]); + unset($import[$iii]); + $import = array_values($import); + $ll = count($import); + } + } + } + /** + * Extract CssAtImportToken and CssAtCharsetToken tokens + */ + for($ii = 0, $ll = count($import); $ii < $ll; $ii++) + { + $class = get_class($import[$ii]); + if ($class === "CssAtImportToken" || $class === "CssAtCharsetToken") + { + $blocks = array_merge($blocks, array_splice($import, $ii, 1, array())); + $ll = count($import); + } + } + /* + * Extract the @font-face, @media and @page at-rule block + */ + for($ii = 0, $ll = count($import); $ii < $ll; $ii++) + { + $class = get_class($import[$ii]); + if ($class === "CssAtFontFaceStartToken" || $class === "CssAtMediaStartToken" || $class === "CssAtPageStartToken" || $class === "CssAtVariablesStartToken") + { + for ($iii = $ii; $iii < $ll; $iii++) + { + $class = get_class($import[$iii]); + if ($class === "CssAtFontFaceEndToken" || $class === "CssAtMediaEndToken" || $class === "CssAtPageEndToken" || $class === "CssAtVariablesEndToken") + { + break; + } + } + $class = get_class($import[$iii]); + if (isset($import[$iii]) && ($class === "CssAtFontFaceEndToken" || $class === "CssAtMediaEndToken" || $class === "CssAtPageEndToken" || $class === "CssAtVariablesEndToken")) + { + $blocks = array_merge($blocks, array_splice($import, $ii, $iii - $ii + 1, array())); + $ll = count($import); + } + } + } + // Create the import array with extracted tokens and the rulesets wrapped into a @media at-rule block + $import = array_merge($blocks, array(new CssAtMediaStartToken($tokens[$i]->MediaTypes)), $import, array(new CssAtMediaEndToken())); + } + // Insert the imported tokens + array_splice($tokens, $i, 1, $import); + // Modify parameters of the for-loop + $i--; + $l = count($tokens); + } + } + } + } + } + +/** + * {@link aCssParserPlugin Parser plugin} for preserve parsing expression() declaration values. + * + * This plugin return no {@link aCssToken CssToken} but ensures that expression() declaration values will get parsed + * properly. + * + * @package CssMin/Parser/Plugins + * @link http://code.google.com/p/cssmin/ + * @author Joe Scylla + * @copyright 2008 - 2011 Joe Scylla + * @license http://opensource.org/licenses/mit-license.php MIT License + * @version 3.0.1 + */ +class CssExpressionParserPlugin extends aCssParserPlugin + { + /** + * Count of left braces. + * + * @var integer + */ + private $leftBraces = 0; + /** + * Count of right braces. + * + * @var integer + */ + private $rightBraces = 0; + /** + * Implements {@link aCssParserPlugin::getTriggerChars()}. + * + * @return array + */ + public function getTriggerChars() + { + return array("(", ")", ";", "}"); + } + /** + * Implements {@link aCssParserPlugin::getTriggerStates()}. + * + * @return array + */ + public function getTriggerStates() + { + return false; + } + /** + * Implements {@link aCssParserPlugin::parse()}. + * + * @param integer $index Current index + * @param string $char Current char + * @param string $previousChar Previous char + * @return mixed TRUE will break the processing; FALSE continue with the next plugin; integer set a new index and break the processing + */ + public function parse($index, $char, $previousChar, $state) + { + // Start of expression + if ($char === "(" && strtolower(substr($this->parser->getSource(), $index - 10, 11)) === "expression(" && $state !== "T_EXPRESSION") + { + $this->parser->pushState("T_EXPRESSION"); + $this->leftBraces++; + } + // Count left braces + elseif ($char === "(" && $state === "T_EXPRESSION") + { + $this->leftBraces++; + } + // Count right braces + elseif ($char === ")" && $state === "T_EXPRESSION") + { + $this->rightBraces++; + } + // Possible end of expression; if left and right braces are equal the expressen ends + elseif (($char === ";" || $char === "}") && $state === "T_EXPRESSION" && $this->leftBraces === $this->rightBraces) + { + $this->leftBraces = $this->rightBraces = 0; + $this->parser->popState(); + return $index - 1; + } + else + { + return false; + } + return true; + } + } + +/** + * CSS Error. + * + * @package CssMin + * @link http://code.google.com/p/cssmin/ + * @author Joe Scylla + * @copyright 2008 - 2011 Joe Scylla + * @license http://opensource.org/licenses/mit-license.php MIT License + * @version 3.0.1 + */ +class CssError + { + /** + * File. + * + * @var string + */ + public $File = ""; + /** + * Line. + * + * @var integer + */ + public $Line = 0; + /** + * Error message. + * + * @var string + */ + public $Message = ""; + /** + * Source. + * + * @var string + */ + public $Source = ""; + /** + * Constructor triggering the error. + * + * @param string $message Error message + * @param string $source Corresponding line [optional] + * @return void + */ + public function __construct($file, $line, $message, $source = "") + { + $this->File = $file; + $this->Line = $line; + $this->Message = $message; + $this->Source = $source; + } + /** + * Returns the error as formatted string. + * + * @return string + */ + public function __toString() + { + return $this->Message . ($this->Source ? ":
" . $this->Source . "": "") . "
in file " . $this->File . " at line " . $this->Line; + } + } + +/** + * This {@link aCssMinifierPlugin} will convert a color value in rgb notation to hexadecimal notation. + * + * Example: + * + * color: rgb(200,60%,5); + * + * + * Will get converted to: + * + * color:#c89905; + * + * + * @package CssMin/Minifier/Plugins + * @link http://code.google.com/p/cssmin/ + * @author Joe Scylla + * @copyright 2008 - 2011 Joe Scylla + * @license http://opensource.org/licenses/mit-license.php MIT License + * @version 3.0.1 + */ +class CssConvertRgbColorsMinifierPlugin extends aCssMinifierPlugin + { + /** + * Regular expression matching the value. + * + * @var string + */ + private $reMatch = "/rgb\s*\(\s*([0-9%]+)\s*,\s*([0-9%]+)\s*,\s*([0-9%]+)\s*\)/iS"; + /** + * Implements {@link aCssMinifierPlugin::minify()}. + * + * @param aCssToken $token Token to process + * @return boolean Return TRUE to break the processing of this token; FALSE to continue + */ + public function apply(aCssToken &$token) + { + if (stripos($token->Value, "rgb") !== false && preg_match($this->reMatch, $token->Value, $m)) + { + for ($i = 1, $l = count($m); $i < $l; $i++) + { + if (strpos("%", $m[$i]) !== false) + { + $m[$i] = substr($m[$i], 0, -1); + $m[$i] = (int) (256 * ($m[$i] / 100)); + } + $m[$i] = str_pad(dechex($m[$i]), 2, "0", STR_PAD_LEFT); + } + $token->Value = str_replace($m[0], "#" . $m[1] . $m[2] . $m[3], $token->Value); + } + return false; + } + /** + * Implements {@link aMinifierPlugin::getTriggerTokens()} + * + * @return array + */ + public function getTriggerTokens() + { + return array + ( + "CssAtFontFaceDeclarationToken", + "CssAtPageDeclarationToken", + "CssRulesetDeclarationToken" + ); + } + } + +/** + * This {@link aCssMinifierPlugin} will convert named color values to hexadecimal notation. + * + * Example: + * + * color: black; + * border: 1px solid indigo; + * + * + * Will get converted to: + * + * color:#000; + * border:1px solid #4b0082; + * + * + * @package CssMin/Minifier/Plugins + * @link http://code.google.com/p/cssmin/ + * @author Joe Scylla + * @copyright 2008 - 2011 Joe Scylla + * @license http://opensource.org/licenses/mit-license.php MIT License + * @version 3.0.1 + */ +class CssConvertNamedColorsMinifierPlugin extends aCssMinifierPlugin + { + + /** + * Regular expression matching the value. + * + * @var string + */ + private $reMatch = null; + /** + * Regular expression replacing the value. + * + * @var string + */ + private $reReplace = "\"\${1}\" . \$this->transformation[strtolower(\"\${2}\")] . \"\${3}\""; + /** + * Transformation table used by the {@link CssConvertNamedColorsMinifierPlugin::$reReplace replace regular expression}. + * + * @var array + */ + private $transformation = array + ( + "aliceblue" => "#f0f8ff", + "antiquewhite" => "#faebd7", + "aqua" => "#0ff", + "aquamarine" => "#7fffd4", + "azure" => "#f0ffff", + "beige" => "#f5f5dc", + "black" => "#000", + "blue" => "#00f", + "blueviolet" => "#8a2be2", + "brown" => "#a52a2a", + "burlywood" => "#deb887", + "cadetblue" => "#5f9ea0", + "chartreuse" => "#7fff00", + "chocolate" => "#d2691e", + "coral" => "#ff7f50", + "cornflowerblue" => "#6495ed", + "cornsilk" => "#fff8dc", + "crimson" => "#dc143c", + "darkblue" => "#00008b", + "darkcyan" => "#008b8b", + "darkgoldenrod" => "#b8860b", + "darkgray" => "#a9a9a9", + "darkgreen" => "#006400", + "darkkhaki" => "#bdb76b", + "darkmagenta" => "#8b008b", + "darkolivegreen" => "#556b2f", + "darkorange" => "#ff8c00", + "darkorchid" => "#9932cc", + "darkred" => "#8b0000", + "darksalmon" => "#e9967a", + "darkseagreen" => "#8fbc8f", + "darkslateblue" => "#483d8b", + "darkslategray" => "#2f4f4f", + "darkturquoise" => "#00ced1", + "darkviolet" => "#9400d3", + "deeppink" => "#ff1493", + "deepskyblue" => "#00bfff", + "dimgray" => "#696969", + "dodgerblue" => "#1e90ff", + "firebrick" => "#b22222", + "floralwhite" => "#fffaf0", + "forestgreen" => "#228b22", + "fuchsia" => "#f0f", + "gainsboro" => "#dcdcdc", + "ghostwhite" => "#f8f8ff", + "gold" => "#ffd700", + "goldenrod" => "#daa520", + "gray" => "#808080", + "green" => "#008000", + "greenyellow" => "#adff2f", + "honeydew" => "#f0fff0", + "hotpink" => "#ff69b4", + "indianred" => "#cd5c5c", + "indigo" => "#4b0082", + "ivory" => "#fffff0", + "khaki" => "#f0e68c", + "lavender" => "#e6e6fa", + "lavenderblush" => "#fff0f5", + "lawngreen" => "#7cfc00", + "lemonchiffon" => "#fffacd", + "lightblue" => "#add8e6", + "lightcoral" => "#f08080", + "lightcyan" => "#e0ffff", + "lightgoldenrodyellow" => "#fafad2", + "lightgreen" => "#90ee90", + "lightgrey" => "#d3d3d3", + "lightpink" => "#ffb6c1", + "lightsalmon" => "#ffa07a", + "lightseagreen" => "#20b2aa", + "lightskyblue" => "#87cefa", + "lightslategray" => "#789", + "lightsteelblue" => "#b0c4de", + "lightyellow" => "#ffffe0", + "lime" => "#0f0", + "limegreen" => "#32cd32", + "linen" => "#faf0e6", + "maroon" => "#800000", + "mediumaquamarine" => "#66cdaa", + "mediumblue" => "#0000cd", + "mediumorchid" => "#ba55d3", + "mediumpurple" => "#9370db", + "mediumseagreen" => "#3cb371", + "mediumslateblue" => "#7b68ee", + "mediumspringgreen" => "#00fa9a", + "mediumturquoise" => "#48d1cc", + "mediumvioletred" => "#c71585", + "midnightblue" => "#191970", + "mintcream" => "#f5fffa", + "mistyrose" => "#ffe4e1", + "moccasin" => "#ffe4b5", + "navajowhite" => "#ffdead", + "navy" => "#000080", + "oldlace" => "#fdf5e6", + "olive" => "#808000", + "olivedrab" => "#6b8e23", + "orange" => "#ffa500", + "orangered" => "#ff4500", + "orchid" => "#da70d6", + "palegoldenrod" => "#eee8aa", + "palegreen" => "#98fb98", + "paleturquoise" => "#afeeee", + "palevioletred" => "#db7093", + "papayawhip" => "#ffefd5", + "peachpuff" => "#ffdab9", + "peru" => "#cd853f", + "pink" => "#ffc0cb", + "plum" => "#dda0dd", + "powderblue" => "#b0e0e6", + "purple" => "#800080", + "red" => "#f00", + "rosybrown" => "#bc8f8f", + "royalblue" => "#4169e1", + "saddlebrown" => "#8b4513", + "salmon" => "#fa8072", + "sandybrown" => "#f4a460", + "seagreen" => "#2e8b57", + "seashell" => "#fff5ee", + "sienna" => "#a0522d", + "silver" => "#c0c0c0", + "skyblue" => "#87ceeb", + "slateblue" => "#6a5acd", + "slategray" => "#708090", + "snow" => "#fffafa", + "springgreen" => "#00ff7f", + "steelblue" => "#4682b4", + "tan" => "#d2b48c", + "teal" => "#008080", + "thistle" => "#d8bfd8", + "tomato" => "#ff6347", + "turquoise" => "#40e0d0", + "violet" => "#ee82ee", + "wheat" => "#f5deb3", + "white" => "#fff", + "whitesmoke" => "#f5f5f5", + "yellow" => "#ff0", + "yellowgreen" => "#9acd32" + ); + /** + * Overwrites {@link aCssMinifierPlugin::__construct()}. + * + * The constructor will create the {@link CssConvertNamedColorsMinifierPlugin::$reReplace replace regular expression} + * based on the {@link CssConvertNamedColorsMinifierPlugin::$transformation transformation table}. + * + * @param CssMinifier $minifier The CssMinifier object of this plugin. + * @param array $configuration Plugin configuration [optional] + * @return void + */ + public function __construct(CssMinifier $minifier, array $configuration = array()) + { + $this->reMatch = "/(^|\s)+(" . implode("|", array_keys($this->transformation)) . ")(\s|$)+/eiS"; + parent::__construct($minifier, $configuration); + } + /** + * Implements {@link aCssMinifierPlugin::minify()}. + * + * @param aCssToken $token Token to process + * @return boolean Return TRUE to break the processing of this token; FALSE to continue + */ + public function apply(aCssToken &$token) + { + $lcValue = strtolower($token->Value); + // Declaration value equals a value in the transformation table => simple replace + if (isset($this->transformation[$lcValue])) + { + $token->Value = $this->transformation[$lcValue]; + } + // Declaration value contains a value in the transformation table => regular expression replace + elseif (preg_match($this->reMatch, $token->Value)) + { + $token->Value = preg_replace($this->reMatch, $this->reReplace, $token->Value); + } + return false; + } + /** + * Implements {@link aMinifierPlugin::getTriggerTokens()} + * + * @return array + */ + public function getTriggerTokens() + { + return array + ( + "CssAtFontFaceDeclarationToken", + "CssAtPageDeclarationToken", + "CssRulesetDeclarationToken" + ); + } + } + +/** + * This {@link aCssMinifierFilter minifier filter} triggers on CSS Level 3 properties and will add declaration tokens + * with browser-specific properties. + * + * @package CssMin/Minifier/Filters + * @link http://code.google.com/p/cssmin/ + * @author Joe Scylla + * @copyright 2008 - 2011 Joe Scylla + * @license http://opensource.org/licenses/mit-license.php MIT License + * @version 3.0.1 + */ +class CssConvertLevel3PropertiesMinifierFilter extends aCssMinifierFilter + { + /** + * Css property transformations table. Used to convert CSS3 and proprietary properties to the browser-specific + * counterparts. + * + * @var array + */ + private $transformations = array + ( + // Property Array(Mozilla, Webkit, Opera, Internet Explorer); NULL values are placeholders and will get ignored + "animation" => array(null, "-webkit-animation", null, null), + "animation-delay" => array(null, "-webkit-animation-delay", null, null), + "animation-direction" => array(null, "-webkit-animation-direction", null, null), + "animation-duration" => array(null, "-webkit-animation-duration", null, null), + "animation-fill-mode" => array(null, "-webkit-animation-fill-mode", null, null), + "animation-iteration-count" => array(null, "-webkit-animation-iteration-count", null, null), + "animation-name" => array(null, "-webkit-animation-name", null, null), + "animation-play-state" => array(null, "-webkit-animation-play-state", null, null), + "animation-timing-function" => array(null, "-webkit-animation-timing-function", null, null), + "appearance" => array("-moz-appearance", "-webkit-appearance", null, null), + "backface-visibility" => array(null, "-webkit-backface-visibility", null, null), + "background-clip" => array(null, "-webkit-background-clip", null, null), + "background-composite" => array(null, "-webkit-background-composite", null, null), + "background-inline-policy" => array("-moz-background-inline-policy", null, null, null), + "background-origin" => array(null, "-webkit-background-origin", null, null), + "background-position-x" => array(null, null, null, "-ms-background-position-x"), + "background-position-y" => array(null, null, null, "-ms-background-position-y"), + "background-size" => array(null, "-webkit-background-size", null, null), + "behavior" => array(null, null, null, "-ms-behavior"), + "binding" => array("-moz-binding", null, null, null), + "border-after" => array(null, "-webkit-border-after", null, null), + "border-after-color" => array(null, "-webkit-border-after-color", null, null), + "border-after-style" => array(null, "-webkit-border-after-style", null, null), + "border-after-width" => array(null, "-webkit-border-after-width", null, null), + "border-before" => array(null, "-webkit-border-before", null, null), + "border-before-color" => array(null, "-webkit-border-before-color", null, null), + "border-before-style" => array(null, "-webkit-border-before-style", null, null), + "border-before-width" => array(null, "-webkit-border-before-width", null, null), + "border-border-bottom-colors" => array("-moz-border-bottom-colors", null, null, null), + "border-bottom-left-radius" => array("-moz-border-radius-bottomleft", "-webkit-border-bottom-left-radius", null, null), + "border-bottom-right-radius" => array("-moz-border-radius-bottomright", "-webkit-border-bottom-right-radius", null, null), + "border-end" => array("-moz-border-end", "-webkit-border-end", null, null), + "border-end-color" => array("-moz-border-end-color", "-webkit-border-end-color", null, null), + "border-end-style" => array("-moz-border-end-style", "-webkit-border-end-style", null, null), + "border-end-width" => array("-moz-border-end-width", "-webkit-border-end-width", null, null), + "border-fit" => array(null, "-webkit-border-fit", null, null), + "border-horizontal-spacing" => array(null, "-webkit-border-horizontal-spacing", null, null), + "border-image" => array("-moz-border-image", "-webkit-border-image", null, null), + "border-left-colors" => array("-moz-border-left-colors", null, null, null), + "border-radius" => array("-moz-border-radius", "-webkit-border-radius", null, null), + "border-border-right-colors" => array("-moz-border-right-colors", null, null, null), + "border-start" => array("-moz-border-start", "-webkit-border-start", null, null), + "border-start-color" => array("-moz-border-start-color", "-webkit-border-start-color", null, null), + "border-start-style" => array("-moz-border-start-style", "-webkit-border-start-style", null, null), + "border-start-width" => array("-moz-border-start-width", "-webkit-border-start-width", null, null), + "border-top-colors" => array("-moz-border-top-colors", null, null, null), + "border-top-left-radius" => array("-moz-border-radius-topleft", "-webkit-border-top-left-radius", null, null), + "border-top-right-radius" => array("-moz-border-radius-topright", "-webkit-border-top-right-radius", null, null), + "border-vertical-spacing" => array(null, "-webkit-border-vertical-spacing", null, null), + "box-align" => array("-moz-box-align", "-webkit-box-align", null, null), + "box-direction" => array("-moz-box-direction", "-webkit-box-direction", null, null), + "box-flex" => array("-moz-box-flex", "-webkit-box-flex", null, null), + "box-flex-group" => array(null, "-webkit-box-flex-group", null, null), + "box-flex-lines" => array(null, "-webkit-box-flex-lines", null, null), + "box-ordinal-group" => array("-moz-box-ordinal-group", "-webkit-box-ordinal-group", null, null), + "box-orient" => array("-moz-box-orient", "-webkit-box-orient", null, null), + "box-pack" => array("-moz-box-pack", "-webkit-box-pack", null, null), + "box-reflect" => array(null, "-webkit-box-reflect", null, null), + "box-shadow" => array("-moz-box-shadow", "-webkit-box-shadow", null, null), + "box-sizing" => array("-moz-box-sizing", null, null, null), + "color-correction" => array(null, "-webkit-color-correction", null, null), + "column-break-after" => array(null, "-webkit-column-break-after", null, null), + "column-break-before" => array(null, "-webkit-column-break-before", null, null), + "column-break-inside" => array(null, "-webkit-column-break-inside", null, null), + "column-count" => array("-moz-column-count", "-webkit-column-count", null, null), + "column-gap" => array("-moz-column-gap", "-webkit-column-gap", null, null), + "column-rule" => array("-moz-column-rule", "-webkit-column-rule", null, null), + "column-rule-color" => array("-moz-column-rule-color", "-webkit-column-rule-color", null, null), + "column-rule-style" => array("-moz-column-rule-style", "-webkit-column-rule-style", null, null), + "column-rule-width" => array("-moz-column-rule-width", "-webkit-column-rule-width", null, null), + "column-span" => array(null, "-webkit-column-span", null, null), + "column-width" => array("-moz-column-width", "-webkit-column-width", null, null), + "columns" => array(null, "-webkit-columns", null, null), + "filter" => array(__CLASS__, "filter"), + "float-edge" => array("-moz-float-edge", null, null, null), + "font-feature-settings" => array("-moz-font-feature-settings", null, null, null), + "font-language-override" => array("-moz-font-language-override", null, null, null), + "font-size-delta" => array(null, "-webkit-font-size-delta", null, null), + "font-smoothing" => array(null, "-webkit-font-smoothing", null, null), + "force-broken-image-icon" => array("-moz-force-broken-image-icon", null, null, null), + "highlight" => array(null, "-webkit-highlight", null, null), + "hyphenate-character" => array(null, "-webkit-hyphenate-character", null, null), + "hyphenate-locale" => array(null, "-webkit-hyphenate-locale", null, null), + "hyphens" => array(null, "-webkit-hyphens", null, null), + "force-broken-image-icon" => array("-moz-image-region", null, null, null), + "ime-mode" => array(null, null, null, "-ms-ime-mode"), + "interpolation-mode" => array(null, null, null, "-ms-interpolation-mode"), + "layout-flow" => array(null, null, null, "-ms-layout-flow"), + "layout-grid" => array(null, null, null, "-ms-layout-grid"), + "layout-grid-char" => array(null, null, null, "-ms-layout-grid-char"), + "layout-grid-line" => array(null, null, null, "-ms-layout-grid-line"), + "layout-grid-mode" => array(null, null, null, "-ms-layout-grid-mode"), + "layout-grid-type" => array(null, null, null, "-ms-layout-grid-type"), + "line-break" => array(null, "-webkit-line-break", null, "-ms-line-break"), + "line-clamp" => array(null, "-webkit-line-clamp", null, null), + "line-grid-mode" => array(null, null, null, "-ms-line-grid-mode"), + "logical-height" => array(null, "-webkit-logical-height", null, null), + "logical-width" => array(null, "-webkit-logical-width", null, null), + "margin-after" => array(null, "-webkit-margin-after", null, null), + "margin-after-collapse" => array(null, "-webkit-margin-after-collapse", null, null), + "margin-before" => array(null, "-webkit-margin-before", null, null), + "margin-before-collapse" => array(null, "-webkit-margin-before-collapse", null, null), + "margin-bottom-collapse" => array(null, "-webkit-margin-bottom-collapse", null, null), + "margin-collapse" => array(null, "-webkit-margin-collapse", null, null), + "margin-end" => array("-moz-margin-end", "-webkit-margin-end", null, null), + "margin-start" => array("-moz-margin-start", "-webkit-margin-start", null, null), + "margin-top-collapse" => array(null, "-webkit-margin-top-collapse", null, null), + "marquee " => array(null, "-webkit-marquee", null, null), + "marquee-direction" => array(null, "-webkit-marquee-direction", null, null), + "marquee-increment" => array(null, "-webkit-marquee-increment", null, null), + "marquee-repetition" => array(null, "-webkit-marquee-repetition", null, null), + "marquee-speed" => array(null, "-webkit-marquee-speed", null, null), + "marquee-style" => array(null, "-webkit-marquee-style", null, null), + "mask" => array(null, "-webkit-mask", null, null), + "mask-attachment" => array(null, "-webkit-mask-attachment", null, null), + "mask-box-image" => array(null, "-webkit-mask-box-image", null, null), + "mask-clip" => array(null, "-webkit-mask-clip", null, null), + "mask-composite" => array(null, "-webkit-mask-composite", null, null), + "mask-image" => array(null, "-webkit-mask-image", null, null), + "mask-origin" => array(null, "-webkit-mask-origin", null, null), + "mask-position" => array(null, "-webkit-mask-position", null, null), + "mask-position-x" => array(null, "-webkit-mask-position-x", null, null), + "mask-position-y" => array(null, "-webkit-mask-position-y", null, null), + "mask-repeat" => array(null, "-webkit-mask-repeat", null, null), + "mask-repeat-x" => array(null, "-webkit-mask-repeat-x", null, null), + "mask-repeat-y" => array(null, "-webkit-mask-repeat-y", null, null), + "mask-size" => array(null, "-webkit-mask-size", null, null), + "match-nearest-mail-blockquote-color" => array(null, "-webkit-match-nearest-mail-blockquote-color", null, null), + "max-logical-height" => array(null, "-webkit-max-logical-height", null, null), + "max-logical-width" => array(null, "-webkit-max-logical-width", null, null), + "min-logical-height" => array(null, "-webkit-min-logical-height", null, null), + "min-logical-width" => array(null, "-webkit-min-logical-width", null, null), + "object-fit" => array(null, null, "-o-object-fit", null), + "object-position" => array(null, null, "-o-object-position", null), + "opacity" => array(__CLASS__, "opacity"), + "outline-radius" => array("-moz-outline-radius", null, null, null), + "outline-bottom-left-radius" => array("-moz-outline-radius-bottomleft", null, null, null), + "outline-bottom-right-radius" => array("-moz-outline-radius-bottomright", null, null, null), + "outline-top-left-radius" => array("-moz-outline-radius-topleft", null, null, null), + "outline-top-right-radius" => array("-moz-outline-radius-topright", null, null, null), + "padding-after" => array(null, "-webkit-padding-after", null, null), + "padding-before" => array(null, "-webkit-padding-before", null, null), + "padding-end" => array("-moz-padding-end", "-webkit-padding-end", null, null), + "padding-start" => array("-moz-padding-start", "-webkit-padding-start", null, null), + "perspective" => array(null, "-webkit-perspective", null, null), + "perspective-origin" => array(null, "-webkit-perspective-origin", null, null), + "perspective-origin-x" => array(null, "-webkit-perspective-origin-x", null, null), + "perspective-origin-y" => array(null, "-webkit-perspective-origin-y", null, null), + "rtl-ordering" => array(null, "-webkit-rtl-ordering", null, null), + "scrollbar-3dlight-color" => array(null, null, null, "-ms-scrollbar-3dlight-color"), + "scrollbar-arrow-color" => array(null, null, null, "-ms-scrollbar-arrow-color"), + "scrollbar-base-color" => array(null, null, null, "-ms-scrollbar-base-color"), + "scrollbar-darkshadow-color" => array(null, null, null, "-ms-scrollbar-darkshadow-color"), + "scrollbar-face-color" => array(null, null, null, "-ms-scrollbar-face-color"), + "scrollbar-highlight-color" => array(null, null, null, "-ms-scrollbar-highlight-color"), + "scrollbar-shadow-color" => array(null, null, null, "-ms-scrollbar-shadow-color"), + "scrollbar-track-color" => array(null, null, null, "-ms-scrollbar-track-color"), + "stack-sizing" => array("-moz-stack-sizing", null, null, null), + "svg-shadow" => array(null, "-webkit-svg-shadow", null, null), + "tab-size" => array("-moz-tab-size", null, "-o-tab-size", null), + "table-baseline" => array(null, null, "-o-table-baseline", null), + "text-align-last" => array(null, null, null, "-ms-text-align-last"), + "text-autospace" => array(null, null, null, "-ms-text-autospace"), + "text-combine" => array(null, "-webkit-text-combine", null, null), + "text-decorations-in-effect" => array(null, "-webkit-text-decorations-in-effect", null, null), + "text-emphasis" => array(null, "-webkit-text-emphasis", null, null), + "text-emphasis-color" => array(null, "-webkit-text-emphasis-color", null, null), + "text-emphasis-position" => array(null, "-webkit-text-emphasis-position", null, null), + "text-emphasis-style" => array(null, "-webkit-text-emphasis-style", null, null), + "text-fill-color" => array(null, "-webkit-text-fill-color", null, null), + "text-justify" => array(null, null, null, "-ms-text-justify"), + "text-kashida-space" => array(null, null, null, "-ms-text-kashida-space"), + "text-overflow" => array(null, null, "-o-text-overflow", "-ms-text-overflow"), + "text-security" => array(null, "-webkit-text-security", null, null), + "text-size-adjust" => array(null, "-webkit-text-size-adjust", null, "-ms-text-size-adjust"), + "text-stroke" => array(null, "-webkit-text-stroke", null, null), + "text-stroke-color" => array(null, "-webkit-text-stroke-color", null, null), + "text-stroke-width" => array(null, "-webkit-text-stroke-width", null, null), + "text-underline-position" => array(null, null, null, "-ms-text-underline-position"), + "transform" => array("-moz-transform", "-webkit-transform", "-o-transform", null), + "transform-origin" => array("-moz-transform-origin", "-webkit-transform-origin", "-o-transform-origin", null), + "transform-origin-x" => array(null, "-webkit-transform-origin-x", null, null), + "transform-origin-y" => array(null, "-webkit-transform-origin-y", null, null), + "transform-origin-z" => array(null, "-webkit-transform-origin-z", null, null), + "transform-style" => array(null, "-webkit-transform-style", null, null), + "transition" => array("-moz-transition", "-webkit-transition", "-o-transition", null), + "transition-delay" => array("-moz-transition-delay", "-webkit-transition-delay", "-o-transition-delay", null), + "transition-duration" => array("-moz-transition-duration", "-webkit-transition-duration", "-o-transition-duration", null), + "transition-property" => array("-moz-transition-property", "-webkit-transition-property", "-o-transition-property", null), + "transition-timing-function" => array("-moz-transition-timing-function", "-webkit-transition-timing-function", "-o-transition-timing-function", null), + "user-drag" => array(null, "-webkit-user-drag", null, null), + "user-focus" => array("-moz-user-focus", null, null, null), + "user-input" => array("-moz-user-input", null, null, null), + "user-modify" => array("-moz-user-modify", "-webkit-user-modify", null, null), + "user-select" => array("-moz-user-select", "-webkit-user-select", null, null), + "white-space" => array(__CLASS__, "whiteSpace"), + "window-shadow" => array("-moz-window-shadow", null, null, null), + "word-break" => array(null, null, null, "-ms-word-break"), + "word-wrap" => array(null, null, null, "-ms-word-wrap"), + "writing-mode" => array(null, "-webkit-writing-mode", null, "-ms-writing-mode"), + "zoom" => array(null, null, null, "-ms-zoom") + ); + /** + * Implements {@link aCssMinifierFilter::filter()}. + * + * @param array $tokens Array of objects of type aCssToken + * @return integer Count of added, changed or removed tokens; a return value large than 0 will rebuild the array + */ + public function apply(array &$tokens) + { + $r = 0; + $transformations = &$this->transformations; + for ($i = 0, $l = count($tokens); $i < $l; $i++) + { + if (get_class($tokens[$i]) === "CssRulesetDeclarationToken") + { + $tProperty = $tokens[$i]->Property; + if (isset($transformations[$tProperty])) + { + $result = array(); + if (is_callable($transformations[$tProperty])) + { + $result = call_user_func_array($transformations[$tProperty], array($tokens[$i])); + if (!is_array($result) && is_object($result)) + { + $result = array($result); + } + } + else + { + $tValue = $tokens[$i]->Value; + $tMediaTypes = $tokens[$i]->MediaTypes; + foreach ($transformations[$tProperty] as $property) + { + if ($property !== null) + { + $result[] = new CssRulesetDeclarationToken($property, $tValue, $tMediaTypes); + } + } + } + if (count($result) > 0) + { + array_splice($tokens, $i + 1, 0, $result); + $i += count($result); + $l += count($result); + } + } + } + } + return $r; + } + /** + * Transforms the Internet Explorer specific declaration property "filter" to Internet Explorer 8+ compatible + * declaratiopn property "-ms-filter". + * + * @param aCssToken $token + * @return array + */ + private static function filter($token) + { + $r = array + ( + new CssRulesetDeclarationToken("-ms-filter", "\"" . $token->Value . "\"", $token->MediaTypes), + ); + return $r; + } + /** + * Transforms "opacity: {value}" into browser specific counterparts. + * + * @param aCssToken $token + * @return array + */ + private static function opacity($token) + { + // Calculate the value for Internet Explorer filter statement + $ieValue = (int) ((float) $token->Value * 100); + $r = array + ( + // Internet Explorer >= 8 + new CssRulesetDeclarationToken("-ms-filter", "\"alpha(opacity=" . $ieValue . ")\"", $token->MediaTypes), + // Internet Explorer >= 4 <= 7 + new CssRulesetDeclarationToken("filter", "alpha(opacity=" . $ieValue . ")", $token->MediaTypes), + new CssRulesetDeclarationToken("zoom", "1", $token->MediaTypes) + ); + return $r; + } + /** + * Transforms "white-space: pre-wrap" into browser specific counterparts. + * + * @param aCssToken $token + * @return array + */ + private static function whiteSpace($token) + { + if (strtolower($token->Value) === "pre-wrap") + { + $r = array + ( + // Firefox < 3 + new CssRulesetDeclarationToken("white-space", "-moz-pre-wrap", $token->MediaTypes), + // Webkit + new CssRulesetDeclarationToken("white-space", "-webkit-pre-wrap", $token->MediaTypes), + // Opera >= 4 <= 6 + new CssRulesetDeclarationToken("white-space", "-pre-wrap", $token->MediaTypes), + // Opera >= 7 + new CssRulesetDeclarationToken("white-space", "-o-pre-wrap", $token->MediaTypes), + // Internet Explorer >= 5.5 + new CssRulesetDeclarationToken("word-wrap", "break-word", $token->MediaTypes) + ); + return $r; + } + else + { + return array(); + } + } + } + +/** + * This {@link aCssMinifierFilter minifier filter} will convert @keyframes at-rule block to browser specific counterparts. + * + * @package CssMin/Minifier/Filters + * @link http://code.google.com/p/cssmin/ + * @author Joe Scylla + * @copyright 2008 - 2011 Joe Scylla + * @license http://opensource.org/licenses/mit-license.php MIT License + * @version 3.0.1 + */ +class CssConvertLevel3AtKeyframesMinifierFilter extends aCssMinifierFilter + { + /** + * Implements {@link aCssMinifierFilter::filter()}. + * + * @param array $tokens Array of objects of type aCssToken + * @return integer Count of added, changed or removed tokens; a return value larger than 0 will rebuild the array + */ + public function apply(array &$tokens) + { + $r = 0; + $transformations = array("-moz-keyframes", "-webkit-keyframes", "-ms-keyframes", "-o-keyframes"); + for ($i = 0, $l = count($tokens); $i < $l; $i++) + { + if (get_class($tokens[$i]) === "CssAtKeyframesStartToken") + { + for ($ii = $i; $ii < $l; $ii++) + { + if (get_class($tokens[$ii]) === "CssAtKeyframesEndToken") + { + break; + } + } + if (get_class($tokens[$ii]) === "CssAtKeyframesEndToken") + { + $add = array(); + $source = array(); + for ($iii = $i; $iii <= $ii; $iii++) + { + $source[] = clone($tokens[$iii]); + } + foreach ($transformations as $transformation) + { + $t = array(); + foreach ($source as $token) + { + $t[] = clone($token); + } + $t[0]->AtRuleName = $transformation; + $add = array_merge($add, $t); + } + if (isset($this->configuration["RemoveSource"]) && $this->configuration["RemoveSource"] === true) + { + array_splice($tokens, $i, $ii - $i + 1, $add); + } + else + { + array_splice($tokens, $ii + 1, 0, $add); + } + $l = count($tokens); + $i = $ii + count($add); + $r += count($add); + } + } + } + return $r; + } + } + +/** + * This {@link aCssMinifierPlugin} will convert a color value in hsl notation to hexadecimal notation. + * + * Example: + * + * color: hsl(232,36%,48%); + * + * + * Will get converted to: + * + * color:#4e5aa7; + * + * + * @package CssMin/Minifier/Plugins + * @link http://code.google.com/p/cssmin/ + * @author Joe Scylla + * @copyright 2008 - 2011 Joe Scylla + * @license http://opensource.org/licenses/mit-license.php MIT License + * @version 3.0.1 + */ +class CssConvertHslColorsMinifierPlugin extends aCssMinifierPlugin + { + /** + * Regular expression matching the value. + * + * @var string + */ + private $reMatch = "/^hsl\s*\(\s*([0-9]+)\s*,\s*([0-9]+)\s*%\s*,\s*([0-9]+)\s*%\s*\)/iS"; + /** + * Implements {@link aCssMinifierPlugin::minify()}. + * + * @param aCssToken $token Token to process + * @return boolean Return TRUE to break the processing of this token; FALSE to continue + */ + public function apply(aCssToken &$token) + { + if (stripos($token->Value, "hsl") !== false && preg_match($this->reMatch, $token->Value, $m)) + { + $token->Value = str_replace($m[0], $this->hsl2hex($m[1], $m[2], $m[3]), $token->Value); + } + return false; + } + /** + * Implements {@link aMinifierPlugin::getTriggerTokens()} + * + * @return array + */ + public function getTriggerTokens() + { + return array + ( + "CssAtFontFaceDeclarationToken", + "CssAtPageDeclarationToken", + "CssRulesetDeclarationToken" + ); + } + /** + * Convert a HSL value to hexadecimal notation. + * + * Based on: {@link http://www.easyrgb.com/index.php?X=MATH&H=19#text19}. + * + * @param integer $hue Hue + * @param integer $saturation Saturation + * @param integer $lightness Lightnesss + * @return string + */ + private function hsl2hex($hue, $saturation, $lightness) + { + $hue = $hue / 360; + $saturation = $saturation / 100; + $lightness = $lightness / 100; + if ($saturation == 0) + { + $red = $lightness * 255; + $green = $lightness * 255; + $blue = $lightness * 255; + } + else + { + if ($lightness < 0.5 ) + { + $v2 = $lightness * (1 + $saturation); + } + else + { + $v2 = ($lightness + $saturation) - ($saturation * $lightness); + } + $v1 = 2 * $lightness - $v2; + $red = 255 * self::hue2rgb($v1, $v2, $hue + (1 / 3)); + $green = 255 * self::hue2rgb($v1, $v2, $hue); + $blue = 255 * self::hue2rgb($v1, $v2, $hue - (1 / 3)); + } + return "#" . str_pad(dechex(round($red)), 2, "0", STR_PAD_LEFT) . str_pad(dechex(round($green)), 2, "0", STR_PAD_LEFT) . str_pad(dechex(round($blue)), 2, "0", STR_PAD_LEFT); + } + /** + * Apply hue to a rgb color value. + * + * @param integer $v1 Value 1 + * @param integer $v2 Value 2 + * @param integer $hue Hue + * @return integer + */ + private function hue2rgb($v1, $v2, $hue) + { + if ($hue < 0) + { + $hue += 1; + } + if ($hue > 1) + { + $hue -= 1; + } + if ((6 * $hue) < 1) + { + return ($v1 + ($v2 - $v1) * 6 * $hue); + } + if ((2 * $hue) < 1) + { + return ($v2); + } + if ((3 * $hue) < 2) + { + return ($v1 + ($v2 - $v1) * (( 2 / 3) - $hue) * 6); + } + return $v1; + } + } + +/** + * This {@link aCssMinifierPlugin} will convert the font-weight values normal and bold to their numeric notation. + * + * Example: + * + * font-weight: normal; + * font: bold 11px monospace; + * + * + * Will get converted to: + * + * font-weight:400; + * font:700 11px monospace; + * + * + * @package CssMin/Minifier/Pluginsn + * @link http://code.google.com/p/cssmin/ + * @author Joe Scylla + * @copyright 2008 - 2011 Joe Scylla + * @license http://opensource.org/licenses/mit-license.php MIT License + * @version 3.0.1 + */ +class CssConvertFontWeightMinifierPlugin extends aCssMinifierPlugin + { + /** + * Array of included declaration properties this plugin will process; others declaration properties will get + * ignored. + * + * @var array + */ + private $include = array + ( + "font", + "font-weight" + ); + /** + * Regular expression matching the value. + * + * @var string + */ + private $reMatch = null; + /** + * Regular expression replace the value. + * + * @var string + */ + private $reReplace = "\"\${1}\" . \$this->transformation[\"\${2}\"] . \"\${3}\""; + /** + * Transformation table used by the {@link CssConvertFontWeightMinifierPlugin::$reReplace replace regular expression}. + * + * @var array + */ + private $transformation = array + ( + "normal" => "400", + "bold" => "700" + ); + /** + * Overwrites {@link aCssMinifierPlugin::__construct()}. + * + * The constructor will create the {@link CssConvertFontWeightMinifierPlugin::$reReplace replace regular expression} + * based on the {@link CssConvertFontWeightMinifierPlugin::$transformation transformation table}. + * + * @param CssMinifier $minifier The CssMinifier object of this plugin. + * @return void + */ + public function __construct(CssMinifier $minifier) + { + $this->reMatch = "/(^|\s)+(" . implode("|", array_keys($this->transformation)). ")(\s|$)+/eiS"; + parent::__construct($minifier); + } + /** + * Implements {@link aCssMinifierPlugin::minify()}. + * + * @param aCssToken $token Token to process + * @return boolean Return TRUE to break the processing of this token; FALSE to continue + */ + public function apply(aCssToken &$token) + { + if (in_array($token->Property, $this->include) && preg_match($this->reMatch, $token->Value, $m)) + { + $token->Value = preg_replace($this->reMatch, $this->reReplace, $token->Value); + } + return false; + } + /** + * Implements {@link aMinifierPlugin::getTriggerTokens()} + * + * @return array + */ + public function getTriggerTokens() + { + return array + ( + "CssAtFontFaceDeclarationToken", + "CssAtPageDeclarationToken", + "CssRulesetDeclarationToken" + ); + } + } + +/** + * This {@link aCssMinifierPlugin} will compress several unit values to their short notations. Examples: + * + * + * padding: 0.5em; + * border: 0px; + * margin: 0 0 0 0; + * + * + * Will get compressed to: + * + * + * padding:.5px; + * border:0; + * margin:0; + * + * + * -- + * + * @package CssMin/Minifier/Plugins + * @link http://code.google.com/p/cssmin/ + * @author Joe Scylla + * @copyright 2008 - 2011 Joe Scylla + * @license http://opensource.org/licenses/mit-license.php MIT License + * @version 3.0.1 + */ +class CssCompressUnitValuesMinifierPlugin extends aCssMinifierPlugin + { + /** + * Regular expression used for matching and replacing unit values. + * + * @var array + */ + private $re = array + ( + "/(^| |-)0\.([0-9]+?)(0+)?(%|em|ex|px|in|cm|mm|pt|pc)/iS" => "\${1}.\${2}\${4}", + "/(^| )-?(\.?)0(%|em|ex|px|in|cm|mm|pt|pc)/iS" => "\${1}0", + "/(^0\s0\s0\s0)|(^0\s0\s0$)|(^0\s0$)/iS" => "0" + ); + /** + * Regular expression matching the value. + * + * @var string + */ + private $reMatch = "/(^| |-)0\.([0-9]+?)(0+)?(%|em|ex|px|in|cm|mm|pt|pc)|(^| )-?(\.?)0(%|em|ex|px|in|cm|mm|pt|pc)|(^0\s0\s0\s0$)|(^0\s0\s0$)|(^0\s0$)/iS"; + /** + * Implements {@link aCssMinifierPlugin::minify()}. + * + * @param aCssToken $token Token to process + * @return boolean Return TRUE to break the processing of this token; FALSE to continue + */ + public function apply(aCssToken &$token) + { + if (preg_match($this->reMatch, $token->Value)) + { + foreach ($this->re as $reMatch => $reReplace) + { + $token->Value = preg_replace($reMatch, $reReplace, $token->Value); + } + } + return false; + } + /** + * Implements {@link aMinifierPlugin::getTriggerTokens()} + * + * @return array + */ + public function getTriggerTokens() + { + return array + ( + "CssAtFontFaceDeclarationToken", + "CssAtPageDeclarationToken", + "CssRulesetDeclarationToken" + ); + } + } + +/** + * This {@link aCssMinifierPlugin} compress the content of expresssion() declaration values. + * + * For compression of expressions {@link https://github.com/rgrove/jsmin-php/ JSMin} will get used. JSMin have to be + * already included or loadable via {@link http://goo.gl/JrW54 PHP autoloading}. + * + * @package CssMin/Minifier/Plugins + * @link http://code.google.com/p/cssmin/ + * @author Joe Scylla + * @copyright 2008 - 2011 Joe Scylla + * @license http://opensource.org/licenses/mit-license.php MIT License + * @version 3.0.1 + */ +class CssCompressExpressionValuesMinifierPlugin extends aCssMinifierPlugin + { + /** + * Implements {@link aCssMinifierPlugin::minify()}. + * + * @param aCssToken $token Token to process + * @return boolean Return TRUE to break the processing of this token; FALSE to continue + */ + public function apply(aCssToken &$token) + { + if (class_exists("JSMin") && stripos($token->Value, "expression(") !== false) + { + $value = $token->Value; + $value = substr($token->Value, stripos($token->Value, "expression(") + 10); + $value = trim(JSMin::minify($value)); + $token->Value = "expression(" . $value . ")"; + } + return false; + } + /** + * Implements {@link aMinifierPlugin::getTriggerTokens()} + * + * @return array + */ + public function getTriggerTokens() + { + return array + ( + "CssAtFontFaceDeclarationToken", + "CssAtPageDeclarationToken", + "CssRulesetDeclarationToken" + ); + } + } + +/** + * This {@link aCssMinifierPlugin} will convert hexadecimal color value with 6 chars to their 3 char hexadecimal + * notation (if possible). + * + * Example: + * + * color: #aabbcc; + * + * + * Will get converted to: + * + * color:#abc; + * + * + * @package CssMin/Minifier/Plugins + * @link http://code.google.com/p/cssmin/ + * @author Joe Scylla + * @copyright 2008 - 2011 Joe Scylla + * @license http://opensource.org/licenses/mit-license.php MIT License + * @version 3.0.1 + */ +class CssCompressColorValuesMinifierPlugin extends aCssMinifierPlugin + { + /** + * Regular expression matching 6 char hexadecimal color values. + * + * @var string + */ + private $reMatch = "/\#([0-9a-f]{6})/iS"; + /** + * Implements {@link aCssMinifierPlugin::minify()}. + * + * @param aCssToken $token Token to process + * @return boolean Return TRUE to break the processing of this token; FALSE to continue + */ + public function apply(aCssToken &$token) + { + if (strpos($token->Value, "#") !== false && preg_match($this->reMatch, $token->Value, $m)) + { + $value = strtolower($m[1]); + if ($value[0] == $value[1] && $value[2] == $value[3] && $value[4] == $value[5]) + { + $token->Value = str_replace($m[0], "#" . $value[0] . $value[2] . $value[4], $token->Value); + } + } + return false; + } + /** + * Implements {@link aMinifierPlugin::getTriggerTokens()} + * + * @return array + */ + public function getTriggerTokens() + { + return array + ( + "CssAtFontFaceDeclarationToken", + "CssAtPageDeclarationToken", + "CssRulesetDeclarationToken" + ); + } + } + +/** + * This {@link aCssToken CSS token} represents a CSS comment. + * + * @package CssMin/Tokens + * @link http://code.google.com/p/cssmin/ + * @author Joe Scylla + * @copyright 2008 - 2011 Joe Scylla + * @license http://opensource.org/licenses/mit-license.php MIT License + * @version 3.0.1 + */ +class CssCommentToken extends aCssToken + { + /** + * Comment as Text. + * + * @var string + */ + public $Comment = ""; + /** + * Set the properties of a comment token. + * + * @param string $comment Comment including comment delimiters + * @return void + */ + public function __construct($comment) + { + $this->Comment = $comment; + } + /** + * Implements {@link aCssToken::__toString()}. + * + * @return string + */ + public function __toString() + { + return $this->Comment; + } + } + +/** + * {@link aCssParserPlugin Parser plugin} for parsing comments. + * + * Adds a {@link CssCommentToken} to the parser if a comment was found. + * + * @package CssMin/Parser/Plugins + * @link http://code.google.com/p/cssmin/ + * @author Joe Scylla + * @copyright 2008 - 2011 Joe Scylla + * @license http://opensource.org/licenses/mit-license.php MIT License + * @version 3.0.1 + */ +class CssCommentParserPlugin extends aCssParserPlugin + { + /** + * Implements {@link aCssParserPlugin::getTriggerChars()}. + * + * @return array + */ + public function getTriggerChars() + { + return array("*", "/"); + } + /** + * Implements {@link aCssParserPlugin::getTriggerStates()}. + * + * @return array + */ + public function getTriggerStates() + { + return false; + } + /** + * Stored buffer for restore. + * + * @var string + */ + private $restoreBuffer = ""; + /** + * Implements {@link aCssParserPlugin::parse()}. + * + * @param integer $index Current index + * @param string $char Current char + * @param string $previousChar Previous char + * @return mixed TRUE will break the processing; FALSE continue with the next plugin; integer set a new index and break the processing + */ + public function parse($index, $char, $previousChar, $state) + { + if ($char === "*" && $previousChar === "/" && $state !== "T_COMMENT") + { + $this->parser->pushState("T_COMMENT"); + $this->parser->setExclusive(__CLASS__); + $this->restoreBuffer = substr($this->parser->getAndClearBuffer(), 0, -2); + } + elseif ($char === "/" && $previousChar === "*" && $state === "T_COMMENT") + { + $this->parser->popState(); + $this->parser->unsetExclusive(); + $this->parser->appendToken(new CssCommentToken("/*" . $this->parser->getAndClearBuffer())); + $this->parser->setBuffer($this->restoreBuffer); + } + else + { + return false; + } + return true; + } + } + +/** + * This {@link aCssToken CSS token} represents the start of a @variables at-rule block. + * + * @package CssMin/Tokens + * @link http://code.google.com/p/cssmin/ + * @author Joe Scylla + * @copyright 2008 - 2011 Joe Scylla + * @license http://opensource.org/licenses/mit-license.php MIT License + * @version 3.0.1 + */ +class CssAtVariablesStartToken extends aCssAtBlockStartToken + { + /** + * Media types of the @variables at-rule block. + * + * @var array + */ + public $MediaTypes = array(); + /** + * Set the properties of a @variables at-rule token. + * + * @param array $mediaTypes Media types + * @return void + */ + public function __construct($mediaTypes = null) + { + $this->MediaTypes = $mediaTypes ? $mediaTypes : array("all"); + } + /** + * Implements {@link aCssToken::__toString()}. + * + * @return string + */ + public function __toString() + { + return ""; + } + } + +/** + * {@link aCssParserPlugin Parser plugin} for parsing @variables at-rule block with including declarations. + * + * Found @variables at-rule blocks will add a {@link CssAtVariablesStartToken} and {@link CssAtVariablesEndToken} to the + * parser; including declarations as {@link CssAtVariablesDeclarationToken}. + * + * @package CssMin/Parser/Plugins + * @link http://code.google.com/p/cssmin/ + * @author Joe Scylla + * @copyright 2008 - 2011 Joe Scylla + * @license http://opensource.org/licenses/mit-license.php MIT License + * @version 3.0.1 + */ +class CssAtVariablesParserPlugin extends aCssParserPlugin + { + /** + * Implements {@link aCssParserPlugin::getTriggerChars()}. + * + * @return array + */ + public function getTriggerChars() + { + return array("@", "{", "}", ":", ";"); + } + /** + * Implements {@link aCssParserPlugin::getTriggerStates()}. + * + * @return array + */ + public function getTriggerStates() + { + return array("T_DOCUMENT", "T_AT_VARIABLES::PREPARE", "T_AT_VARIABLES", "T_AT_VARIABLES_DECLARATION"); + } + /** + * Implements {@link aCssParserPlugin::parse()}. + * + * @param integer $index Current index + * @param string $char Current char + * @param string $previousChar Previous char + * @return mixed TRUE will break the processing; FALSE continue with the next plugin; integer set a new index and break the processing + */ + public function parse($index, $char, $previousChar, $state) + { + // Start of @variables at-rule block + if ($char === "@" && $state === "T_DOCUMENT" && strtolower(substr($this->parser->getSource(), $index, 10)) === "@variables") + { + $this->parser->pushState("T_AT_VARIABLES::PREPARE"); + $this->parser->clearBuffer(); + return $index + 10; + } + // Start of @variables declarations + elseif ($char === "{" && $state === "T_AT_VARIABLES::PREPARE") + { + $this->parser->setState("T_AT_VARIABLES"); + $mediaTypes = array_filter(array_map("trim", explode(",", $this->parser->getAndClearBuffer("{")))); + $this->parser->appendToken(new CssAtVariablesStartToken($mediaTypes)); + } + // Start of @variables declaration + if ($char === ":" && $state === "T_AT_VARIABLES") + { + $this->buffer = $this->parser->getAndClearBuffer(":"); + $this->parser->pushState("T_AT_VARIABLES_DECLARATION"); + } + // Unterminated @variables declaration + elseif ($char === ":" && $state === "T_AT_VARIABLES_DECLARATION") + { + // Ignore Internet Explorer filter declarations + if ($this->buffer === "filter") + { + return false; + } + CssMin::triggerError(new CssError(__FILE__, __LINE__, __METHOD__ . ": Unterminated @variables declaration", $this->buffer . ":" . $this->parser->getBuffer() . "_")); + } + // End of @variables declaration + elseif (($char === ";" || $char === "}") && $state === "T_AT_VARIABLES_DECLARATION") + { + $value = $this->parser->getAndClearBuffer(";}"); + if (strtolower(substr($value, -10, 10)) === "!important") + { + $value = trim(substr($value, 0, -10)); + $isImportant = true; + } + else + { + $isImportant = false; + } + $this->parser->popState(); + $this->parser->appendToken(new CssAtVariablesDeclarationToken($this->buffer, $value, $isImportant)); + $this->buffer = ""; + } + // End of @variables at-rule block + elseif ($char === "}" && $state === "T_AT_VARIABLES") + { + $this->parser->popState(); + $this->parser->clearBuffer(); + $this->parser->appendToken(new CssAtVariablesEndToken()); + } + else + { + return false; + } + return true; + } + } + +/** + * This {@link aCssToken CSS token} represents the end of a @variables at-rule block. + * + * @package CssMin/Tokens + * @link http://code.google.com/p/cssmin/ + * @author Joe Scylla + * @copyright 2008 - 2011 Joe Scylla + * @license http://opensource.org/licenses/mit-license.php MIT License + * @version 3.0.1 + */ +class CssAtVariablesEndToken extends aCssAtBlockEndToken + { + /** + * Implements {@link aCssToken::__toString()}. + * + * @return string + */ + public function __toString() + { + return ""; + } + } + +/** + * This {@link aCssToken CSS token} represents a declaration of a @variables at-rule block. + * + * @package CssMin/Tokens + * @link http://code.google.com/p/cssmin/ + * @author Joe Scylla + * @copyright 2008 - 2011 Joe Scylla + * @license http://opensource.org/licenses/mit-license.php MIT License + * @version 3.0.1 + */ +class CssAtVariablesDeclarationToken extends aCssDeclarationToken + { + /** + * Implements {@link aCssToken::__toString()}. + * + * @return string + */ + public function __toString() + { + return ""; + } + } + +/** +* This {@link aCssToken CSS token} represents the start of a @page at-rule block. + * + * @package CssMin/Tokens + * @link http://code.google.com/p/cssmin/ + * @author Joe Scylla + * @copyright 2008 - 2011 Joe Scylla + * @license http://opensource.org/licenses/mit-license.php MIT License + * @version 3.0.1 + */ +class CssAtPageStartToken extends aCssAtBlockStartToken + { + /** + * Selector. + * + * @var string + */ + public $Selector = ""; + /** + * Sets the properties of the @page at-rule. + * + * @param string $selector Selector + * @return void + */ + public function __construct($selector = "") + { + $this->Selector = $selector; + } + /** + * Implements {@link aCssToken::__toString()}. + * + * @return string + */ + public function __toString() + { + return "@page" . ($this->Selector ? " " . $this->Selector : "") . "{"; + } + } + +/** + * {@link aCssParserPlugin Parser plugin} for parsing @page at-rule block with including declarations. + * + * Found @page at-rule blocks will add a {@link CssAtPageStartToken} and {@link CssAtPageEndToken} to the + * parser; including declarations as {@link CssAtPageDeclarationToken}. + * + * @package CssMin/Parser/Plugins + * @link http://code.google.com/p/cssmin/ + * @author Joe Scylla + * @copyright 2008 - 2011 Joe Scylla + * @license http://opensource.org/licenses/mit-license.php MIT License + * @version 3.0.1 + */ +class CssAtPageParserPlugin extends aCssParserPlugin + { + /** + * Implements {@link aCssParserPlugin::getTriggerChars()}. + * + * @return array + */ + public function getTriggerChars() + { + return array("@", "{", "}", ":", ";"); + } + /** + * Implements {@link aCssParserPlugin::getTriggerStates()}. + * + * @return array + */ + public function getTriggerStates() + { + return array("T_DOCUMENT", "T_AT_PAGE::SELECTOR", "T_AT_PAGE", "T_AT_PAGE_DECLARATION"); + } + /** + * Implements {@link aCssParserPlugin::parse()}. + * + * @param integer $index Current index + * @param string $char Current char + * @param string $previousChar Previous char + * @return mixed TRUE will break the processing; FALSE continue with the next plugin; integer set a new index and break the processing + */ + public function parse($index, $char, $previousChar, $state) + { + // Start of @page at-rule block + if ($char === "@" && $state === "T_DOCUMENT" && strtolower(substr($this->parser->getSource(), $index, 5)) === "@page") + { + $this->parser->pushState("T_AT_PAGE::SELECTOR"); + $this->parser->clearBuffer(); + return $index + 5; + } + // Start of @page declarations + elseif ($char === "{" && $state === "T_AT_PAGE::SELECTOR") + { + $selector = $this->parser->getAndClearBuffer("{"); + $this->parser->setState("T_AT_PAGE"); + $this->parser->clearBuffer(); + $this->parser->appendToken(new CssAtPageStartToken($selector)); + } + // Start of @page declaration + elseif ($char === ":" && $state === "T_AT_PAGE") + { + $this->parser->pushState("T_AT_PAGE_DECLARATION"); + $this->buffer = $this->parser->getAndClearBuffer(":", true); + } + // Unterminated @font-face declaration + elseif ($char === ":" && $state === "T_AT_PAGE_DECLARATION") + { + // Ignore Internet Explorer filter declarations + if ($this->buffer === "filter") + { + return false; + } + CssMin::triggerError(new CssError(__FILE__, __LINE__, __METHOD__ . ": Unterminated @page declaration", $this->buffer . ":" . $this->parser->getBuffer() . "_")); + } + // End of @page declaration + elseif (($char === ";" || $char === "}") && $state == "T_AT_PAGE_DECLARATION") + { + $value = $this->parser->getAndClearBuffer(";}"); + if (strtolower(substr($value, -10, 10)) == "!important") + { + $value = trim(substr($value, 0, -10)); + $isImportant = true; + } + else + { + $isImportant = false; + } + $this->parser->popState(); + $this->parser->appendToken(new CssAtPageDeclarationToken($this->buffer, $value, $isImportant)); + // -- + if ($char === "}") + { + $this->parser->popState(); + $this->parser->appendToken(new CssAtPageEndToken()); + } + $this->buffer = ""; + } + // End of @page at-rule block + elseif ($char === "}" && $state === "T_AT_PAGE") + { + $this->parser->popState(); + $this->parser->clearBuffer(); + $this->parser->appendToken(new CssAtPageEndToken()); + } + else + { + return false; + } + return true; + } + } + +/** + * This {@link aCssToken CSS token} represents the end of a @page at-rule block. + * + * @package CssMin/Tokens + * @link http://code.google.com/p/cssmin/ + * @author Joe Scylla + * @copyright 2008 - 2011 Joe Scylla + * @license http://opensource.org/licenses/mit-license.php MIT License + * @version 3.0.1 + */ +class CssAtPageEndToken extends aCssAtBlockEndToken + { + + } + +/** + * This {@link aCssToken CSS token} represents a declaration of a @page at-rule block. + * + * @package CssMin/Tokens + * @link http://code.google.com/p/cssmin/ + * @author Joe Scylla + * @copyright 2008 - 2011 Joe Scylla + * @license http://opensource.org/licenses/mit-license.php MIT License + * @version 3.0.1 + */ +class CssAtPageDeclarationToken extends aCssDeclarationToken + { + + } + +/** + * This {@link aCssToken CSS token} represents the start of a @media at-rule block. + * + * @package CssMin/Tokens + * @link http://code.google.com/p/cssmin/ + * @author Joe Scylla + * @copyright 2008 - 2011 Joe Scylla + * @license http://opensource.org/licenses/mit-license.php MIT License + * @version 3.0.1 + */ +class CssAtMediaStartToken extends aCssAtBlockStartToken + { + /** + * Sets the properties of the @media at-rule. + * + * @param array $mediaTypes Media types + * @return void + */ + public function __construct(array $mediaTypes = array()) + { + $this->MediaTypes = $mediaTypes; + } + /** + * Implements {@link aCssToken::__toString()}. + * + * @return string + */ + public function __toString() + { + return "@media " . implode(",", $this->MediaTypes) . "{"; + } + } + +/** + * {@link aCssParserPlugin Parser plugin} for parsing @media at-rule block. + * + * Found @media at-rule blocks will add a {@link CssAtMediaStartToken} and {@link CssAtMediaEndToken} to the parser. + * This plugin will also set the the current media types using {@link CssParser::setMediaTypes()} and + * {@link CssParser::unsetMediaTypes()}. + * + * @package CssMin/Parser/Plugins + * @link http://code.google.com/p/cssmin/ + * @author Joe Scylla + * @copyright 2008 - 2011 Joe Scylla + * @license http://opensource.org/licenses/mit-license.php MIT License + * @version 3.0.1 + */ +class CssAtMediaParserPlugin extends aCssParserPlugin + { + /** + * Implements {@link aCssParserPlugin::getTriggerChars()}. + * + * @return array + */ + public function getTriggerChars() + { + return array("@", "{", "}"); + } + /** + * Implements {@link aCssParserPlugin::getTriggerStates()}. + * + * @return array + */ + public function getTriggerStates() + { + return array("T_DOCUMENT", "T_AT_MEDIA::PREPARE", "T_AT_MEDIA"); + } + /** + * Implements {@link aCssParserPlugin::parse()}. + * + * @param integer $index Current index + * @param string $char Current char + * @param string $previousChar Previous char + * @return mixed TRUE will break the processing; FALSE continue with the next plugin; integer set a new index and break the processing + */ + public function parse($index, $char, $previousChar, $state) + { + if ($char === "@" && $state === "T_DOCUMENT" && strtolower(substr($this->parser->getSource(), $index, 6)) === "@media") + { + $this->parser->pushState("T_AT_MEDIA::PREPARE"); + $this->parser->clearBuffer(); + return $index + 6; + } + elseif ($char === "{" && $state === "T_AT_MEDIA::PREPARE") + { + $mediaTypes = array_filter(array_map("trim", explode(",", $this->parser->getAndClearBuffer("{")))); + $this->parser->setMediaTypes($mediaTypes); + $this->parser->setState("T_AT_MEDIA"); + $this->parser->appendToken(new CssAtMediaStartToken($mediaTypes)); + } + elseif ($char === "}" && $state === "T_AT_MEDIA") + { + $this->parser->appendToken(new CssAtMediaEndToken()); + $this->parser->clearBuffer(); + $this->parser->unsetMediaTypes(); + $this->parser->popState(); + } + else + { + return false; + } + return true; + } + } + +/** + * This {@link aCssToken CSS token} represents the end of a @media at-rule block. + * + * @package CssMin/Tokens + * @link http://code.google.com/p/cssmin/ + * @author Joe Scylla + * @copyright 2008 - 2011 Joe Scylla + * @license http://opensource.org/licenses/mit-license.php MIT License + * @version 3.0.1 + */ +class CssAtMediaEndToken extends aCssAtBlockEndToken + { + + } + +/** + * This {@link aCssToken CSS token} represents the start of a @keyframes at-rule block. + * + * @package CssMin/Tokens + * @link http://code.google.com/p/cssmin/ + * @author Joe Scylla + * @copyright 2008 - 2011 Joe Scylla + * @license http://opensource.org/licenses/mit-license.php MIT License + * @version 3.0.1 + */ +class CssAtKeyframesStartToken extends aCssAtBlockStartToken + { + /** + * Name of the at-rule. + * + * @var string + */ + public $AtRuleName = "keyframes"; + /** + * Name + * + * @var string + */ + public $Name = ""; + /** + * Sets the properties of the @page at-rule. + * + * @param string $selector Selector + * @return void + */ + public function __construct($name, $atRuleName = null) + { + $this->Name = $name; + if (!is_null($atRuleName)) + { + $this->AtRuleName = $atRuleName; + } + } + /** + * Implements {@link aCssToken::__toString()}. + * + * @return string + */ + public function __toString() + { + return "@" . $this->AtRuleName . " \"" . $this->Name . "\"{"; + } + } + +/** + * This {@link aCssToken CSS token} represents the start of a ruleset of a @keyframes at-rule block. + * + * @package CssMin/Tokens + * @link http://code.google.com/p/cssmin/ + * @author Joe Scylla + * @copyright 2008 - 2011 Joe Scylla + * @license http://opensource.org/licenses/mit-license.php MIT License + * @version 3.0.1 + */ +class CssAtKeyframesRulesetStartToken extends aCssRulesetStartToken + { + /** + * Array of selectors. + * + * @var array + */ + public $Selectors = array(); + /** + * Set the properties of a ruleset token. + * + * @param array $selectors Selectors of the ruleset + * @return void + */ + public function __construct(array $selectors = array()) + { + $this->Selectors = $selectors; + } + /** + * Implements {@link aCssToken::__toString()}. + * + * @return string + */ + public function __toString() + { + return implode(",", $this->Selectors) . "{"; + } + } + +/** + * This {@link aCssToken CSS token} represents the end of a ruleset of a @keyframes at-rule block. + * + * @package CssMin/Tokens + * @link http://code.google.com/p/cssmin/ + * @author Joe Scylla + * @copyright 2008 - 2011 Joe Scylla + * @license http://opensource.org/licenses/mit-license.php MIT License + * @version 3.0.1 + */ +class CssAtKeyframesRulesetEndToken extends aCssRulesetEndToken + { + + } + +/** + * This {@link aCssToken CSS token} represents a ruleset declaration of a @keyframes at-rule block. + * + * @package CssMin/Tokens + * @link http://code.google.com/p/cssmin/ + * @author Joe Scylla + * @copyright 2008 - 2011 Joe Scylla + * @license http://opensource.org/licenses/mit-license.php MIT License + * @version 3.0.1 + */ +class CssAtKeyframesRulesetDeclarationToken extends aCssDeclarationToken + { + + } + +/** + * {@link aCssParserPlugin Parser plugin} for parsing @keyframes at-rule blocks, rulesets and declarations. + * + * @package CssMin/Parser/Plugins + * @link http://code.google.com/p/cssmin/ + * @author Joe Scylla + * @copyright 2008 - 2011 Joe Scylla + * @license http://opensource.org/licenses/mit-license.php MIT License + * @version 3.0.1 + */ +class CssAtKeyframesParserPlugin extends aCssParserPlugin + { + /** + * @var string Keyword + */ + private $atRuleName = ""; + /** + * Selectors. + * + * @var array + */ + private $selectors = array(); + /** + * Implements {@link aCssParserPlugin::getTriggerChars()}. + * + * @return array + */ + public function getTriggerChars() + { + return array("@", "{", "}", ":", ",", ";"); + } + /** + * Implements {@link aCssParserPlugin::getTriggerStates()}. + * + * @return array + */ + public function getTriggerStates() + { + return array("T_DOCUMENT", "T_AT_KEYFRAMES::NAME", "T_AT_KEYFRAMES", "T_AT_KEYFRAMES_RULESETS", "T_AT_KEYFRAMES_RULESET", "T_AT_KEYFRAMES_RULESET_DECLARATION"); + } + /** + * Implements {@link aCssParserPlugin::parse()}. + * + * @param integer $index Current index + * @param string $char Current char + * @param string $previousChar Previous char + * @return mixed TRUE will break the processing; FALSE continue with the next plugin; integer set a new index and break the processing + */ + public function parse($index, $char, $previousChar, $state) + { + // Start of @keyframes at-rule block + if ($char === "@" && $state === "T_DOCUMENT" && strtolower(substr($this->parser->getSource(), $index, 10)) === "@keyframes") + { + $this->atRuleName = "keyframes"; + $this->parser->pushState("T_AT_KEYFRAMES::NAME"); + $this->parser->clearBuffer(); + return $index + 10; + } + // Start of @keyframes at-rule block (@-moz-keyframes) + elseif ($char === "@" && $state === "T_DOCUMENT" && strtolower(substr($this->parser->getSource(), $index, 15)) === "@-moz-keyframes") + { + $this->atRuleName = "-moz-keyframes"; + $this->parser->pushState("T_AT_KEYFRAMES::NAME"); + $this->parser->clearBuffer(); + return $index + 15; + } + // Start of @keyframes at-rule block (@-webkit-keyframes) + elseif ($char === "@" && $state === "T_DOCUMENT" && strtolower(substr($this->parser->getSource(), $index, 18)) === "@-webkit-keyframes") + { + $this->atRuleName = "-webkit-keyframes"; + $this->parser->pushState("T_AT_KEYFRAMES::NAME"); + $this->parser->clearBuffer(); + return $index + 18; + } + // Start of @keyframes at-rule block (@-ms-keyframes) + elseif ($char === "@" && $state === "T_DOCUMENT" && strtolower(substr($this->parser->getSource(), $index, 14)) === "@-ms-keyframes") + { + $this->atRuleName = "-ms-keyframes"; + $this->parser->pushState("T_AT_KEYFRAMES::NAME"); + $this->parser->clearBuffer(); + return $index + 14; + } + // Start of @keyframes at-rule block (@-o-keyframes) + elseif ($char === "@" && $state === "T_DOCUMENT" && strtolower(substr($this->parser->getSource(), $index, 13)) === "@-o-keyframes") + { + $this->atRuleName = "-o-keyframes"; + $this->parser->pushState("T_AT_KEYFRAMES::NAME"); + $this->parser->clearBuffer(); + return $index + 13; + } + // Start of @keyframes rulesets + elseif ($char === "{" && $state === "T_AT_KEYFRAMES::NAME") + { + $name = $this->parser->getAndClearBuffer("{\"'"); + $this->parser->setState("T_AT_KEYFRAMES_RULESETS"); + $this->parser->clearBuffer(); + $this->parser->appendToken(new CssAtKeyframesStartToken($name, $this->atRuleName)); + } + // Start of @keyframe ruleset and selectors + if ($char === "," && $state === "T_AT_KEYFRAMES_RULESETS") + { + $this->selectors[] = $this->parser->getAndClearBuffer(",{"); + } + // Start of a @keyframes ruleset + elseif ($char === "{" && $state === "T_AT_KEYFRAMES_RULESETS") + { + if ($this->parser->getBuffer() !== "") + { + $this->selectors[] = $this->parser->getAndClearBuffer(",{"); + $this->parser->pushState("T_AT_KEYFRAMES_RULESET"); + $this->parser->appendToken(new CssAtKeyframesRulesetStartToken($this->selectors)); + $this->selectors = array(); + } + } + // Start of @keyframes ruleset declaration + elseif ($char === ":" && $state === "T_AT_KEYFRAMES_RULESET") + { + $this->parser->pushState("T_AT_KEYFRAMES_RULESET_DECLARATION"); + $this->buffer = $this->parser->getAndClearBuffer(":;", true); + } + // Unterminated @keyframes ruleset declaration + elseif ($char === ":" && $state === "T_AT_KEYFRAMES_RULESET_DECLARATION") + { + // Ignore Internet Explorer filter declarations + if ($this->buffer === "filter") + { + return false; + } + CssMin::triggerError(new CssError(__FILE__, __LINE__, __METHOD__ . ": Unterminated @keyframes ruleset declaration", $this->buffer . ":" . $this->parser->getBuffer() . "_")); + } + // End of declaration + elseif (($char === ";" || $char === "}") && $state === "T_AT_KEYFRAMES_RULESET_DECLARATION") + { + $value = $this->parser->getAndClearBuffer(";}"); + if (strtolower(substr($value, -10, 10)) === "!important") + { + $value = trim(substr($value, 0, -10)); + $isImportant = true; + } + else + { + $isImportant = false; + } + $this->parser->popState(); + $this->parser->appendToken(new CssAtKeyframesRulesetDeclarationToken($this->buffer, $value, $isImportant)); + // Declaration ends with a right curly brace; so we have to end the ruleset + if ($char === "}") + { + $this->parser->appendToken(new CssAtKeyframesRulesetEndToken()); + $this->parser->popState(); + } + $this->buffer = ""; + } + // End of @keyframes ruleset + elseif ($char === "}" && $state === "T_AT_KEYFRAMES_RULESET") + { + $this->parser->clearBuffer(); + + $this->parser->popState(); + $this->parser->appendToken(new CssAtKeyframesRulesetEndToken()); + } + // End of @keyframes rulesets + elseif ($char === "}" && $state === "T_AT_KEYFRAMES_RULESETS") + { + $this->parser->clearBuffer(); + $this->parser->popState(); + $this->parser->appendToken(new CssAtKeyframesEndToken()); + } + else + { + return false; + } + return true; + } + } + +/** + * This {@link aCssToken CSS token} represents the end of a @keyframes at-rule block. + * + * @package CssMin/Tokens + * @link http://code.google.com/p/cssmin/ + * @author Joe Scylla + * @copyright 2008 - 2011 Joe Scylla + * @license http://opensource.org/licenses/mit-license.php MIT License + * @version 3.0.1 + */ +class CssAtKeyframesEndToken extends aCssAtBlockEndToken + { + + } + +/** + * This {@link aCssToken CSS token} represents a @import at-rule. + * + * @package CssMin/Tokens + * @link http://code.google.com/p/cssmin/ + * @author Joe Scylla + * @copyright 2008 - 2011 Joe Scylla + * @license http://opensource.org/licenses/mit-license.php MIT License + * @version 3.0.1.b1 (2001-02-22) + */ +class CssAtImportToken extends aCssToken + { + /** + * Import path of the @import at-rule. + * + * @var string + */ + public $Import = ""; + /** + * Media types of the @import at-rule. + * + * @var array + */ + public $MediaTypes = array(); + /** + * Set the properties of a @import at-rule token. + * + * @param string $import Import path + * @param array $mediaTypes Media types + * @return void + */ + public function __construct($import, $mediaTypes) + { + $this->Import = $import; + $this->MediaTypes = $mediaTypes ? $mediaTypes : array(); + } + /** + * Implements {@link aCssToken::__toString()}. + * + * @return string + */ + public function __toString() + { + return "@import \"" . $this->Import . "\"" . (count($this->MediaTypes) > 0 ? " " . implode(",", $this->MediaTypes) : ""). ";"; + } + } + +/** + * {@link aCssParserPlugin Parser plugin} for parsing @import at-rule. + * + * If a @import at-rule was found this plugin will add a {@link CssAtImportToken} to the parser. + * + * @package CssMin/Parser/Plugins + * @link http://code.google.com/p/cssmin/ + * @author Joe Scylla + * @copyright 2008 - 2011 Joe Scylla + * @license http://opensource.org/licenses/mit-license.php MIT License + * @version 3.0.1 + */ +class CssAtImportParserPlugin extends aCssParserPlugin + { + /** + * Implements {@link aCssParserPlugin::getTriggerChars()}. + * + * @return array + */ + public function getTriggerChars() + { + return array("@", ";", ",", "\n"); + } + /** + * Implements {@link aCssParserPlugin::getTriggerStates()}. + * + * @return array + */ + public function getTriggerStates() + { + return array("T_DOCUMENT", "T_AT_IMPORT"); + } + /** + * Implements {@link aCssParserPlugin::parse()}. + * + * @param integer $index Current index + * @param string $char Current char + * @param string $previousChar Previous char + * @return mixed TRUE will break the processing; FALSE continue with the next plugin; integer set a new index and break the processing + */ + public function parse($index, $char, $previousChar, $state) + { + if ($char === "@" && $state === "T_DOCUMENT" && strtolower(substr($this->parser->getSource(), $index, 7)) === "@import") + { + $this->parser->pushState("T_AT_IMPORT"); + $this->parser->clearBuffer(); + return $index + 7; + } + elseif (($char === ";" || $char === "\n") && $state === "T_AT_IMPORT") + { + $this->buffer = $this->parser->getAndClearBuffer(";"); + $pos = false; + foreach (array(")", "\"", "'") as $needle) + { + if (($pos = strrpos($this->buffer, $needle)) !== false) + { + break; + } + } + $import = substr($this->buffer, 0, $pos + 1); + if (stripos($import, "url(") === 0) + { + $import = substr($import, 4, -1); + } + $import = trim($import, " \t\n\r\0\x0B'\""); + $mediaTypes = array_filter(array_map("trim", explode(",", trim(substr($this->buffer, $pos + 1), " \t\n\r\0\x0B{")))); + if ($pos) + { + $this->parser->appendToken(new CssAtImportToken($import, $mediaTypes)); + } + else + { + CssMin::triggerError(new CssError(__FILE__, __LINE__, __METHOD__ . ": Invalid @import at-rule syntax", $this->parser->buffer)); + } + $this->parser->popState(); + } + else + { + return false; + } + return true; + } + } + +/** + * This {@link aCssToken CSS token} represents the start of a @font-face at-rule block. + * + * @package CssMin/Tokens + * @link http://code.google.com/p/cssmin/ + * @author Joe Scylla + * @copyright 2008 - 2011 Joe Scylla + * @license http://opensource.org/licenses/mit-license.php MIT License + * @version 3.0.1 + */ +class CssAtFontFaceStartToken extends aCssAtBlockStartToken + { + /** + * Implements {@link aCssToken::__toString()}. + * + * @return string + */ + public function __toString() + { + return "@font-face{"; + } + } + +/** + * {@link aCssParserPlugin Parser plugin} for parsing @font-face at-rule block with including declarations. + * + * Found @font-face at-rule blocks will add a {@link CssAtFontFaceStartToken} and {@link CssAtFontFaceEndToken} to the + * parser; including declarations as {@link CssAtFontFaceDeclarationToken}. + * + * @package CssMin/Parser/Plugins + * @link http://code.google.com/p/cssmin/ + * @author Joe Scylla + * @copyright 2008 - 2011 Joe Scylla + * @license http://opensource.org/licenses/mit-license.php MIT License + * @version 3.0.1 + */ +class CssAtFontFaceParserPlugin extends aCssParserPlugin + { + /** + * Implements {@link aCssParserPlugin::getTriggerChars()}. + * + * @return array + */ + public function getTriggerChars() + { + return array("@", "{", "}", ":", ";"); + } + /** + * Implements {@link aCssParserPlugin::getTriggerStates()}. + * + * @return array + */ + public function getTriggerStates() + { + return array("T_DOCUMENT", "T_AT_FONT_FACE::PREPARE", "T_AT_FONT_FACE", "T_AT_FONT_FACE_DECLARATION"); + } + /** + * Implements {@link aCssParserPlugin::parse()}. + * + * @param integer $index Current index + * @param string $char Current char + * @param string $previousChar Previous char + * @return mixed TRUE will break the processing; FALSE continue with the next plugin; integer set a new index and break the processing + */ + public function parse($index, $char, $previousChar, $state) + { + // Start of @font-face at-rule block + if ($char === "@" && $state === "T_DOCUMENT" && strtolower(substr($this->parser->getSource(), $index, 10)) === "@font-face") + { + $this->parser->pushState("T_AT_FONT_FACE::PREPARE"); + $this->parser->clearBuffer(); + return $index + 10; + } + // Start of @font-face declarations + elseif ($char === "{" && $state === "T_AT_FONT_FACE::PREPARE") + { + $this->parser->setState("T_AT_FONT_FACE"); + $this->parser->clearBuffer(); + $this->parser->appendToken(new CssAtFontFaceStartToken()); + } + // Start of @font-face declaration + elseif ($char === ":" && $state === "T_AT_FONT_FACE") + { + $this->parser->pushState("T_AT_FONT_FACE_DECLARATION"); + $this->buffer = $this->parser->getAndClearBuffer(":", true); + } + // Unterminated @font-face declaration + elseif ($char === ":" && $state === "T_AT_FONT_FACE_DECLARATION") + { + // Ignore Internet Explorer filter declarations + if ($this->buffer === "filter") + { + return false; + } + CssMin::triggerError(new CssError(__FILE__, __LINE__, __METHOD__ . ": Unterminated @font-face declaration", $this->buffer . ":" . $this->parser->getBuffer() . "_")); + } + // End of @font-face declaration + elseif (($char === ";" || $char === "}") && $state === "T_AT_FONT_FACE_DECLARATION") + { + $value = $this->parser->getAndClearBuffer(";}"); + if (strtolower(substr($value, -10, 10)) === "!important") + { + $value = trim(substr($value, 0, -10)); + $isImportant = true; + } + else + { + $isImportant = false; + } + $this->parser->popState(); + $this->parser->appendToken(new CssAtFontFaceDeclarationToken($this->buffer, $value, $isImportant)); + $this->buffer = ""; + // -- + if ($char === "}") + { + $this->parser->appendToken(new CssAtFontFaceEndToken()); + $this->parser->popState(); + } + } + // End of @font-face at-rule block + elseif ($char === "}" && $state === "T_AT_FONT_FACE") + { + $this->parser->appendToken(new CssAtFontFaceEndToken()); + $this->parser->clearBuffer(); + $this->parser->popState(); + } + else + { + return false; + } + return true; + } + } + +/** + * This {@link aCssToken CSS token} represents the end of a @font-face at-rule block. + * + * @package CssMin/Tokens + * @link http://code.google.com/p/cssmin/ + * @author Joe Scylla + * @copyright 2008 - 2011 Joe Scylla + * @license http://opensource.org/licenses/mit-license.php MIT License + * @version 3.0.1 + */ +class CssAtFontFaceEndToken extends aCssAtBlockEndToken + { + + } + +/** + * This {@link aCssToken CSS token} represents a declaration of a @font-face at-rule block. + * + * @package CssMin/Tokens + * @link http://code.google.com/p/cssmin/ + * @author Joe Scylla + * @copyright 2008 - 2011 Joe Scylla + * @license http://opensource.org/licenses/mit-license.php MIT License + * @version 3.0.1 + */ +class CssAtFontFaceDeclarationToken extends aCssDeclarationToken + { + + } + +/** + * This {@link aCssToken CSS token} represents a @charset at-rule. + * + * @package CssMin/Tokens + * @link http://code.google.com/p/cssmin/ + * @author Joe Scylla + * @copyright 2008 - 2011 Joe Scylla + * @license http://opensource.org/licenses/mit-license.php MIT License + * @version 3.0.1 + */ +class CssAtCharsetToken extends aCssToken + { + /** + * Charset of the @charset at-rule. + * + * @var string + */ + public $Charset = ""; + /** + * Set the properties of @charset at-rule token. + * + * @param string $charset Charset of the @charset at-rule token + * @return void + */ + public function __construct($charset) + { + $this->Charset = $charset; + } + /** + * Implements {@link aCssToken::__toString()}. + * + * @return string + */ + public function __toString() + { + return "@charset " . $this->Charset . ";"; + } + } + +/** + * {@link aCssParserPlugin Parser plugin} for parsing @charset at-rule. + * + * If a @charset at-rule was found this plugin will add a {@link CssAtCharsetToken} to the parser. + * + * @package CssMin/Parser/Plugins + * @link http://code.google.com/p/cssmin/ + * @author Joe Scylla + * @copyright 2008 - 2011 Joe Scylla + * @license http://opensource.org/licenses/mit-license.php MIT License + * @version 3.0.1 + */ +class CssAtCharsetParserPlugin extends aCssParserPlugin + { + /** + * Implements {@link aCssParserPlugin::getTriggerChars()}. + * + * @return array + */ + public function getTriggerChars() + { + return array("@", ";", "\n"); + } + /** + * Implements {@link aCssParserPlugin::getTriggerStates()}. + * + * @return array + */ + public function getTriggerStates() + { + return array("T_DOCUMENT", "T_AT_CHARSET"); + } + /** + * Implements {@link aCssParserPlugin::parse()}. + * + * @param integer $index Current index + * @param string $char Current char + * @param string $previousChar Previous char + * @return mixed TRUE will break the processing; FALSE continue with the next plugin; integer set a new index and break the processing + */ + public function parse($index, $char, $previousChar, $state) + { + if ($char === "@" && $state === "T_DOCUMENT" && strtolower(substr($this->parser->getSource(), $index, 8)) === "@charset") + { + $this->parser->pushState("T_AT_CHARSET"); + $this->parser->clearBuffer(); + return $index + 8; + } + elseif (($char === ";" || $char === "\n") && $state === "T_AT_CHARSET") + { + $charset = $this->parser->getAndClearBuffer(";"); + $this->parser->popState(); + $this->parser->appendToken(new CssAtCharsetToken($charset)); + } + else + { + return false; + } + return true; + } + } + +?> \ No newline at end of file From 8cc10724ad3ab198908eb69f9c3839c0365b21d2 Mon Sep 17 00:00:00 2001 From: xavier Date: Thu, 17 Jan 2019 11:21:06 +0100 Subject: [PATCH 26/42] Fix translation value & datagrid --- src/DAMBundle/Resources/config/oro/datagrids.yml | 2 +- src/DAMBundle/Resources/views/Document/view.html.twig | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/src/DAMBundle/Resources/config/oro/datagrids.yml b/src/DAMBundle/Resources/config/oro/datagrids.yml index aa96166..4e79a73 100644 --- a/src/DAMBundle/Resources/config/oro/datagrids.yml +++ b/src/DAMBundle/Resources/config/oro/datagrids.yml @@ -174,7 +174,7 @@ datagrids: icon: eye rowAction: true update: - acl_resource: kiboko_project_update + acl_resource: kiboko_dam_document_update type: navigate label: oro.grid.action.update link: update_link diff --git a/src/DAMBundle/Resources/views/Document/view.html.twig b/src/DAMBundle/Resources/views/Document/view.html.twig index 9fe7427..c33aa38 100644 --- a/src/DAMBundle/Resources/views/Document/view.html.twig +++ b/src/DAMBundle/Resources/views/Document/view.html.twig @@ -17,7 +17,7 @@ {% set breadcrumbs = { 'entity': entity, 'indexPath': path('kiboko_dam_index'), - 'indexLabel': 'kiboko.dam.documentnode.entity_plural_label'|trans, + 'indexLabel': 'kiboko.dam.document.entity_plural_label'|trans, 'entityTitle': entity.names|localized_value } %} {{ parent() }} From 45925277e5250dfe3e2b8788b6048b33da5da10f Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Gr=C3=A9gory=20Planchat?= Date: Thu, 17 Jan 2019 11:36:12 +0100 Subject: [PATCH 27/42] Moved a data transformer for document node UUID --- .../DocumentNodeUuidDataTransformer.php | 45 +++++++++++++++++++ .../Form/Type/DocumentNodeUuidType.php | 38 +--------------- 2 files changed, 47 insertions(+), 36 deletions(-) create mode 100644 src/DAMBundle/Form/DataTransformer/DocumentNodeUuidDataTransformer.php diff --git a/src/DAMBundle/Form/DataTransformer/DocumentNodeUuidDataTransformer.php b/src/DAMBundle/Form/DataTransformer/DocumentNodeUuidDataTransformer.php new file mode 100644 index 0000000..6f855e8 --- /dev/null +++ b/src/DAMBundle/Form/DataTransformer/DocumentNodeUuidDataTransformer.php @@ -0,0 +1,45 @@ + UuidInterface::class, + '%actual%' => is_object($value) ? get_class($value) : gettype($value), + ] + )); + } + + return (string) $value; + } + + public function reverseTransform($value) + { + if ($value === null) { + return null; + } + if (!is_string($value)) { + throw new \UnexpectedValueException(strtr( + 'Expected a string, but got a %actual%.', + [ + '%actual%' => is_object($value) ? get_class($value) : gettype($value), + ] + )); + } + + return (new UuidFactory())->fromString($value); + } +} diff --git a/src/DAMBundle/Form/Type/DocumentNodeUuidType.php b/src/DAMBundle/Form/Type/DocumentNodeUuidType.php index 1e75eb7..2fdd3b6 100644 --- a/src/DAMBundle/Form/Type/DocumentNodeUuidType.php +++ b/src/DAMBundle/Form/Type/DocumentNodeUuidType.php @@ -2,6 +2,7 @@ namespace Kiboko\Bundle\DAMBundle\Form\Type; +use DAMBundle\Form\DataTransformer\DocumentNodeUuidDataTransformer; use Kiboko\Bundle\DAMBundle\Entity\DocumentNode; use Ramsey\Uuid\UuidFactory; use Ramsey\Uuid\UuidInterface; @@ -25,42 +26,7 @@ public function buildForm(FormBuilderInterface $builder, array $options) 'readonly' => true, ], ] - )->addModelTransformer(new class implements DataTransformerInterface { - public function transform($value) - { - if ($value === null) { - return null; - } - if (!$value instanceof UuidInterface) { - throw new \UnexpectedValueException(strtr( - 'Expected a %expected% instance, but got a %actual%.', - [ - '%expected%' => UuidInterface::class, - '%actual%' => is_object($value) ? get_class($value) : gettype($value), - ] - )); - } - - return (string) $value; - } - - public function reverseTransform($value) - { - if ($value === null) { - return null; - } - if (!is_string($value)) { - throw new \UnexpectedValueException(strtr( - 'Expected a string, but got a %actual%.', - [ - '%actual%' => is_object($value) ? get_class($value) : gettype($value), - ] - )); - } - - return (new UuidFactory())->fromString($value); - } - }) + )->addModelTransformer(new DocumentNodeUuidDataTransformer()) ); $builder->remove('owner'); From a286aa58dfbee15741e5f4a00b191ba6c937ce4b Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Gr=C3=A9gory=20Planchat?= Date: Thu, 17 Jan 2019 11:48:41 +0100 Subject: [PATCH 28/42] Fixed DI declarations for the DocumentController --- .../Controller/DocumentController.php | 29 +++++++++++-------- .../Form/Handler/DocumentHandler.php | 20 ++++++++----- .../Resources/config/controllers.yml | 12 +++++++- src/DAMBundle/Resources/config/services.yml | 9 ------ 4 files changed, 41 insertions(+), 29 deletions(-) diff --git a/src/DAMBundle/Controller/DocumentController.php b/src/DAMBundle/Controller/DocumentController.php index 1fca74e..c6e72ac 100644 --- a/src/DAMBundle/Controller/DocumentController.php +++ b/src/DAMBundle/Controller/DocumentController.php @@ -4,8 +4,8 @@ use Kiboko\Bundle\DAMBundle\Entity\Document; use Kiboko\Bundle\DAMBundle\Form\Handler\DocumentHandler; -use Kiboko\Bundle\DAMBundle\Form\Type\DocumentType; use Kiboko\Bundle\DAMBundle\Model\DocumentNodeInterface; +use Oro\Bundle\FormBundle\Model\UpdateHandlerFacade; use Oro\Bundle\SecurityBundle\Annotation\Acl; use Oro\Bundle\UIBundle\Route\Router; use Sensio\Bundle\FrameworkExtraBundle\Configuration\ParamConverter; @@ -23,15 +23,20 @@ */ final class DocumentController extends Controller { + /** + * @var DocumentHandler + */ + private $handler; + /** * @var Form */ private $form; /** - * @var DocumentHandler + * @var UpdateHandlerFacade */ - private $handler; + private $updateHandler; /** * @var TranslatorInterface @@ -49,21 +54,23 @@ final class DocumentController extends Controller private $session; /** - * @param Form $form * @param DocumentHandler $handler + * @param Form $form + * @param UpdateHandlerFacade $updateHandler * @param TranslatorInterface $translator * @param Router $router * @param Session $session */ public function __construct( - Form $form, DocumentHandler $handler, + Form $form, + UpdateHandlerFacade $updateHandler, TranslatorInterface $translator, Router $router, Session $session ) { - $this->form = $form; $this->handler = $handler; + $this->form = $form; $this->translator = $translator; $this->router = $router; $this->session = $session; @@ -127,6 +134,7 @@ private function updateWidget( ] ); } + return array_merge( $responseData, [ @@ -168,7 +176,6 @@ public function viewAction(Document $document) ]; } - /** * @param Document $document * @param Request $request @@ -202,12 +209,10 @@ public function updateAction(Document $document, Request $request) protected function update(Document $document, Request $request) { - $form = $this->createForm(DocumentType::class, $document); - - return $this->get('oro_form.update_handler')->update( + return $this->updateHandler->update( $document, - $form, - $this->get('translator')->trans('kiboko.dam.views.document.update.save.label'), + $this->form, + $this->translator->trans('kiboko.dam.views.document.update.save.label'), $request, null ); diff --git a/src/DAMBundle/Form/Handler/DocumentHandler.php b/src/DAMBundle/Form/Handler/DocumentHandler.php index 9f60da9..ddc183f 100644 --- a/src/DAMBundle/Form/Handler/DocumentHandler.php +++ b/src/DAMBundle/Form/Handler/DocumentHandler.php @@ -15,14 +15,20 @@ class DocumentHandler { use RequestHandlerTrait; - /** @var FormInterface */ - protected $form; + /** + * @var FormInterface + */ + private $form; - /** @var RequestStack */ - protected $requestStack; + /** + * @var RequestStack + */ + private $requestStack; - /** @var EntityManager */ - protected $manager; + /** + * @var EntityManager + */ + private $manager; /** * @param FormInterface $form @@ -65,7 +71,7 @@ public function process(Document $entity, DocumentNodeInterface $node) * @param DocumentInterface $entity * @param DocumentNodeInterface $node */ - protected function onSuccess(DocumentInterface $entity, DocumentNodeInterface $node) + private function onSuccess(DocumentInterface $entity, DocumentNodeInterface $node) { $this->manager->persist($entity); $this->manager->flush(); diff --git a/src/DAMBundle/Resources/config/controllers.yml b/src/DAMBundle/Resources/config/controllers.yml index e92c642..e8d32b9 100644 --- a/src/DAMBundle/Resources/config/controllers.yml +++ b/src/DAMBundle/Resources/config/controllers.yml @@ -17,4 +17,14 @@ services: - '@translator' - '@kiboko_dam.form.document.widget.upload_asset' - '@doctrine.orm.entity_manager' - - %kernel.project_dir% \ No newline at end of file + - %kernel.project_dir% + + kiboko_dam.controller.document: + class: Kiboko\Bundle\DAMBundle\Controller\DocumentController + arguments: + - '@kiboko_dam.form.handler.document' + - '@kiboko_dam.form.document' + - '@oro_form.update_handler' + - '@translator' + - '@oro_ui.router' + - '@session' diff --git a/src/DAMBundle/Resources/config/services.yml b/src/DAMBundle/Resources/config/services.yml index 47d7d21..ad4da34 100644 --- a/src/DAMBundle/Resources/config/services.yml +++ b/src/DAMBundle/Resources/config/services.yml @@ -22,15 +22,6 @@ services: - '@request_stack' - '@doctrine.orm.entity_manager' - kiboko_dam.controller.document: - class: Kiboko\Bundle\DAMBundle\Controller\DocumentController - arguments: - - '@kiboko_dam.form.document' - - '@kiboko_dam.form.handler.document' - - '@translator' - - '@oro_ui.router' - - '@session' - kiboko_dam.form.type.document_node: class: Kiboko\Bundle\DAMBundle\Form\Type\DocumentNodeType arguments: From ed895428245f779db8872124e289bd74d1a544f3 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Gr=C3=A9gory=20Planchat?= Date: Thu, 17 Jan 2019 11:59:25 +0100 Subject: [PATCH 29/42] Fixed DI declarations for the AssetWidgetController --- .../Controller/AssetWidgetController.php | 33 +++++++++---------- .../Controller/DocumentController.php | 23 ++++++------- .../Resources/config/controllers.yml | 6 ++-- 3 files changed, 31 insertions(+), 31 deletions(-) diff --git a/src/DAMBundle/Controller/AssetWidgetController.php b/src/DAMBundle/Controller/AssetWidgetController.php index cdbe9f5..bc78533 100644 --- a/src/DAMBundle/Controller/AssetWidgetController.php +++ b/src/DAMBundle/Controller/AssetWidgetController.php @@ -20,21 +20,15 @@ use Symfony\Component\Translation\TranslatorInterface; use Sensio\Bundle\FrameworkExtraBundle\Configuration\ParamConverter; - /** * @Route("/asset-widget", service="kiboko_dam.controller.asset_widget") */ -class AssetWidgetController extends Controller +final class AssetWidgetController extends Controller { /** - * @var ContextHelper - */ - private $helper; - - /** - * @var EntityManager $em + * @var FormInterface */ - private $em; + private $form; /** * @var UpdateHandlerFacade @@ -47,9 +41,14 @@ class AssetWidgetController extends Controller private $translator; /** - * @var FormInterface + * @var ContextHelper */ - private $form; + private $helper; + + /** + * @var EntityManager $em + */ + private $em; /** * @var string @@ -57,25 +56,25 @@ class AssetWidgetController extends Controller private $projectDir; /** - * @param ContextHelper $helper + * @param FormInterface $form * @param UpdateHandlerFacade $formUpdateHandler * @param TranslatorInterface $translator - * @param FormInterface $form + * @param ContextHelper $helper * @param EntityManager $em * @param string $projectDir */ public function __construct( - ContextHelper $helper, + FormInterface $form, UpdateHandlerFacade $formUpdateHandler, TranslatorInterface $translator, - FormInterface $form, + ContextHelper $helper, EntityManager $em, string $projectDir ) { - $this->helper = $helper; + $this->form = $form; $this->formUpdateHandler = $formUpdateHandler; $this->translator = $translator; - $this->form = $form; + $this->helper = $helper; $this->em = $em; $this->projectDir = $projectDir; } diff --git a/src/DAMBundle/Controller/DocumentController.php b/src/DAMBundle/Controller/DocumentController.php index c6e72ac..590ceb4 100644 --- a/src/DAMBundle/Controller/DocumentController.php +++ b/src/DAMBundle/Controller/DocumentController.php @@ -12,7 +12,7 @@ use Sensio\Bundle\FrameworkExtraBundle\Configuration\Route; use Sensio\Bundle\FrameworkExtraBundle\Configuration\Template; use Symfony\Bundle\FrameworkBundle\Controller\Controller; -use Symfony\Component\Form\Form; +use Symfony\Component\Form\FormInterface; use Symfony\Component\HttpFoundation\Request; use Symfony\Component\HttpFoundation\Response; use Symfony\Component\HttpFoundation\Session\Session; @@ -29,14 +29,14 @@ final class DocumentController extends Controller private $handler; /** - * @var Form + * @var FormInterface */ private $form; /** * @var UpdateHandlerFacade */ - private $updateHandler; + private $formUpdateHandler; /** * @var TranslatorInterface @@ -54,24 +54,25 @@ final class DocumentController extends Controller private $session; /** - * @param DocumentHandler $handler - * @param Form $form - * @param UpdateHandlerFacade $updateHandler + * @param FormInterface $form + * @param UpdateHandlerFacade $formUpdateHandler * @param TranslatorInterface $translator + * @param DocumentHandler $handler * @param Router $router * @param Session $session */ public function __construct( - DocumentHandler $handler, - Form $form, - UpdateHandlerFacade $updateHandler, + FormInterface $form, + UpdateHandlerFacade $formUpdateHandler, TranslatorInterface $translator, + DocumentHandler $handler, Router $router, Session $session ) { - $this->handler = $handler; $this->form = $form; + $this->formUpdateHandler = $formUpdateHandler; $this->translator = $translator; + $this->handler = $handler; $this->router = $router; $this->session = $session; } @@ -209,7 +210,7 @@ public function updateAction(Document $document, Request $request) protected function update(Document $document, Request $request) { - return $this->updateHandler->update( + return $this->formUpdateHandler->update( $document, $this->form, $this->translator->trans('kiboko.dam.views.document.update.save.label'), diff --git a/src/DAMBundle/Resources/config/controllers.yml b/src/DAMBundle/Resources/config/controllers.yml index e8d32b9..742b6d0 100644 --- a/src/DAMBundle/Resources/config/controllers.yml +++ b/src/DAMBundle/Resources/config/controllers.yml @@ -12,19 +12,19 @@ services: kiboko_dam.controller.asset_widget: class: Kiboko\Bundle\DAMBundle\Controller\AssetWidgetController arguments: - - '@oro_action.helper.context' + - '@kiboko_dam.form.document.widget.upload_asset' - '@oro_form.update_handler' - '@translator' - - '@kiboko_dam.form.document.widget.upload_asset' + - '@oro_action.helper.context' - '@doctrine.orm.entity_manager' - %kernel.project_dir% kiboko_dam.controller.document: class: Kiboko\Bundle\DAMBundle\Controller\DocumentController arguments: - - '@kiboko_dam.form.handler.document' - '@kiboko_dam.form.document' - '@oro_form.update_handler' - '@translator' + - '@kiboko_dam.form.handler.document' - '@oro_ui.router' - '@session' From 858a45e0459e0894b51ce542320c4b756325f7f4 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Gr=C3=A9gory=20Planchat?= Date: Thu, 17 Jan 2019 12:42:51 +0100 Subject: [PATCH 30/42] Changed routes conventions --- .../Api/Rest/DocumentController.php | 10 +-- .../Api/Rest/DocumentNodeController.php | 8 +- .../Controller/AssetWidgetController.php | 18 ++--- .../Controller/DocumentController.php | 19 +++-- .../Controller/DocumentNodeController.php | 77 +++++++++++-------- .../DocumentNodeTreeAjaxController.php | 69 +++++++++-------- .../Controller/TeamStorageNodeController.php | 11 ++- .../DocumentDatagridListener.php | 13 +--- .../EventListener/NavigationListener.php | 4 +- .../Form/Type/DocumentNodeUuidType.php | 3 - .../JsTree/DocumentNodeUpdateTreeHandler.php | 6 +- .../Resources/config/controllers.yml | 15 ++++ src/DAMBundle/Resources/config/services.yml | 16 ---- .../Resources/views/Document/update.html.twig | 4 +- .../Resources/views/Document/view.html.twig | 2 +- .../views/DocumentNode/update.html.twig | 8 +- .../views/TeamStorageNode/browse.html.twig | 2 +- .../views/TeamStorageNode/update.html.twig | 5 +- .../Resources/views/tree/view.html.twig | 10 +-- .../DocumentNodeTreeAjaxControllerTest.php | 29 +++++++ 20 files changed, 174 insertions(+), 155 deletions(-) create mode 100644 src/DAMBundle/Tests/Functional/Controller/DocumentNodeTreeAjaxControllerTest.php diff --git a/src/DAMBundle/Controller/Api/Rest/DocumentController.php b/src/DAMBundle/Controller/Api/Rest/DocumentController.php index 0270ac2..93a905e 100644 --- a/src/DAMBundle/Controller/Api/Rest/DocumentController.php +++ b/src/DAMBundle/Controller/Api/Rest/DocumentController.php @@ -1,23 +1,17 @@ get('kiboko_dam.document_manager.api'); } -} \ No newline at end of file +} diff --git a/src/DAMBundle/Controller/Api/Rest/DocumentNodeController.php b/src/DAMBundle/Controller/Api/Rest/DocumentNodeController.php index 62160bc..dc612ac 100644 --- a/src/DAMBundle/Controller/Api/Rest/DocumentNodeController.php +++ b/src/DAMBundle/Controller/Api/Rest/DocumentNodeController.php @@ -1,20 +1,16 @@ get('kiboko.document_node_manager.api'); } -} \ No newline at end of file +} diff --git a/src/DAMBundle/Controller/AssetWidgetController.php b/src/DAMBundle/Controller/AssetWidgetController.php index bc78533..d7fd28a 100644 --- a/src/DAMBundle/Controller/AssetWidgetController.php +++ b/src/DAMBundle/Controller/AssetWidgetController.php @@ -80,12 +80,11 @@ public function __construct( } /** - * @param Request $request * @param DocumentNodeInterface $node * - * @Route("/{uuid}", + * @Route("/{node}", * name="kiboko_dam_upload_asset_widget", - * requirements={"uuid"="[\da-f]{8}-[\da-f]{4}-[\da-f]{4}-[\da-f]{4}-[\da-f]{12}"}, + * requirements={"node"="[\da-f]{8}-[\da-f]{4}-[\da-f]{4}-[\da-f]{4}-[\da-f]{12}"}, * options={ * "expose"=true, * }, @@ -94,7 +93,7 @@ public function __construct( * @ParamConverter("node", * class="KibokoDAMBundle:DocumentNode", * options={ - * "mapping": {"uuid": "uuid"}, + * "mapping": {"node": "uuid"}, * "map_method_signature" = true, * } * ) @@ -103,16 +102,15 @@ public function __construct( * * @return array */ - public function widgetAction(Request $request, DocumentNodeInterface $node) + public function widgetAction(DocumentNodeInterface $node) { return [ 'form' => $this->form->createView(), 'formAction' => $this->generateUrl( 'kiboko_dam_upload_asset', [ - 'uuid' => $node->getUuid()->toString(), + 'node' => $node->getUuid()->toString(), ] - ) ]; } @@ -123,16 +121,16 @@ public function widgetAction(Request $request, DocumentNodeInterface $node) * * @return Response * - * @Route("/{uuid}/upload", + * @Route("/{node}/upload", * name="kiboko_dam_upload_asset", - * requirements={"uuid"="[\da-f]{8}-[\da-f]{4}-[\da-f]{4}-[\da-f]{4}-[\da-f]{12}"}, + * requirements={"node"="[\da-f]{8}-[\da-f]{4}-[\da-f]{4}-[\da-f]{4}-[\da-f]{12}"}, * * ) * @Method({"POST", "PUT"}) * @ParamConverter("node", * class="KibokoDAMBundle:DocumentNode", * options={ - * "mapping": {"uuid": "uuid"}, + * "mapping": {"node": "uuid"}, * "map_method_signature" = true, * } * ) diff --git a/src/DAMBundle/Controller/DocumentController.php b/src/DAMBundle/Controller/DocumentController.php index 590ceb4..033a7ec 100644 --- a/src/DAMBundle/Controller/DocumentController.php +++ b/src/DAMBundle/Controller/DocumentController.php @@ -83,11 +83,14 @@ public function __construct( * * @return array|Request * - * @Route("/{uuid}/upload", name="kiboko_dam_document_upload") + * @Route("/{node}/upload", + * name="kiboko_dam_document_upload", + * requirements={"node"="[\da-f]{8}-[\da-f]{4}-[\da-f]{4}-[\da-f]{4}-[\da-f]{12}"}, + * ) * @ParamConverter("node", * class="KibokoDAMBundle:DocumentNode", * options={ - * "mapping": {"uuid": "uuid"}, + * "mapping": {"node": "uuid"}, * "map_method_signature" = true, * } * ) @@ -149,15 +152,15 @@ private function updateWidget( * @param Document $document * @return array|Response * - * @Route("/{uuid}/view", + * @Route("/{node}/view", * name="kiboko_dam_document_view", - * requirements={"uuid"="[\da-f]{8}-[\da-f]{4}-[\da-f]{4}-[\da-f]{4}-[\da-f]{12}"} + * requirements={"node"="[\da-f]{8}-[\da-f]{4}-[\da-f]{4}-[\da-f]{4}-[\da-f]{12}"} * ) * @ParamConverter("document", * class="KibokoDAMBundle:Document", * options={ * "mapping": { - * "uuid": "uuid", + * "node": "uuid", * }, * "map_method_signature" = true, * } @@ -182,15 +185,15 @@ public function viewAction(Document $document) * @param Request $request * @return array|Response * - * @Route("/{uuid}/update", + * @Route("/{node}/update", * name="kiboko_dam_document_update", - * requirements={"uuid"="[\da-f]{8}-[\da-f]{4}-[\da-f]{4}-[\da-f]{4}-[\da-f]{12}"} + * requirements={"node"="[\da-f]{8}-[\da-f]{4}-[\da-f]{4}-[\da-f]{4}-[\da-f]{12}"} * ) * @ParamConverter("document", * class="KibokoDAMBundle:Document", * options={ * "mapping": { - * "uuid": "uuid", + * "node": "uuid", * }, * "map_method_signature" = true, * } diff --git a/src/DAMBundle/Controller/DocumentNodeController.php b/src/DAMBundle/Controller/DocumentNodeController.php index a01b34d..18d0cce 100644 --- a/src/DAMBundle/Controller/DocumentNodeController.php +++ b/src/DAMBundle/Controller/DocumentNodeController.php @@ -63,17 +63,18 @@ public function __construct( /** * @param TeamStorageNode $node + * * @return array|Response * - * @Route("/{uuid}/browse", + * @Route("/{node}/browse", * name="kiboko_dam_node_browse", - * requirements={"uuid"="[\da-f]{8}-[\da-f]{4}-[\da-f]{4}-[\da-f]{4}-[\da-f]{12}"} + * requirements={"node"="[\da-f]{8}-[\da-f]{4}-[\da-f]{4}-[\da-f]{4}-[\da-f]{12}"} * ) * @ParamConverter("node", * class="KibokoDAMBundle:TeamStorageNode", * options={ * "mapping": { - * "uuid": "uuid", + * "node": "uuid", * }, * "map_method_signature" = true, * } @@ -88,7 +89,6 @@ public function __construct( */ public function browseAction(TeamStorageNode $node) { - $path = []; $parent = $node; while (($parent = $parent->getParent()) !== null) { @@ -101,21 +101,25 @@ public function browseAction(TeamStorageNode $node) 'tree' => $this->treeHandler->createTree($node), ]; } + /** - * @param TeamStorageNode $teamStorageNode + * @param TeamStorageNode $root * @param DocumentNode $node + * * @return array|Response * - * @Route("/{uuid}/browse/{uuid2}", + * @Route("/{root}/browse/{node}", * name="kiboko_dam_node_browse_to_node", - * requirements={"uuid"="[\da-f]{8}-[\da-f]{4}-[\da-f]{4}-[\da-f]{4}-[\da-f]{12}", - * "uuid2"="[\da-f]{8}-[\da-f]{4}-[\da-f]{4}-[\da-f]{4}-[\da-f]{12}"} + * requirements={ + * "root"="[\da-f]{8}-[\da-f]{4}-[\da-f]{4}-[\da-f]{4}-[\da-f]{12}", + * "node"="[\da-f]{8}-[\da-f]{4}-[\da-f]{4}-[\da-f]{4}-[\da-f]{12}" + * } * ) - * @ParamConverter("teamstoragenode", + * @ParamConverter("root", * class="KibokoDAMBundle:TeamStorageNode", * options={ * "mapping": { - * "uuid": "uuid", + * "root": "uuid", * }, * "map_method_signature" = true, * } @@ -124,7 +128,7 @@ public function browseAction(TeamStorageNode $node) * class="KibokoDAMBundle:DocumentNode", * options={ * "mapping": { - * "uuid2": "uuid", + * "node": "uuid", * }, * "map_method_signature" = true, * } @@ -137,20 +141,19 @@ public function browseAction(TeamStorageNode $node) * ) * @Template("@KibokoDAM/DocumentNode/browse.html.twig") */ - public function browseToNodeAction(TeamStorageNode $teamStorageNode, DocumentNode $node) + public function browseToNodeAction(TeamStorageNode $root, DocumentNode $node) { - $path = []; - $parent = $teamStorageNode; + $parent = $root; while (($parent = $parent->getParent()) !== null) { $path[] = $parent; } return [ - 'teamstorage' => $teamStorageNode, + 'teamstorage' => $root, 'node' => $node, 'path' => $path, - 'tree' => $this->treeHandler->createTree($teamStorageNode, $node), + 'tree' => $this->treeHandler->createTree($root, $node), ]; } @@ -159,30 +162,30 @@ public function browseToNodeAction(TeamStorageNode $teamStorageNode, DocumentNod * * @param DocumentNodeInterface $parent * @param DocumentNodeInterface $root - * @return array|Response * + * @return array|Response * - * @Route("/{root}/create/{uuid}", + * @Route("/{root}/create/{parent}", * name="kiboko_dam_node_create", * requirements={ * "root"="[\da-f]{8}-[\da-f]{4}-[\da-f]{4}-[\da-f]{4}-[\da-f]{12}", - * "uuid"="[\da-f]{8}-[\da-f]{4}-[\da-f]{4}-[\da-f]{4}-[\da-f]{12}" + * "parent"="[\da-f]{8}-[\da-f]{4}-[\da-f]{4}-[\da-f]{4}-[\da-f]{12}" * }, * options={ * "expose"=true, * } * ) - * @ParamConverter("parent", + * @ParamConverter("root", * class="KibokoDAMBundle:DocumentNode", * options={ - * "mapping": {"uuid": "uuid"}, + * "mapping": {"root": "uuid"}, * "map_method_signature" = true, * } * ) - * @ParamConverter("root", + * @ParamConverter("parent", * class="KibokoDAMBundle:DocumentNode", * options={ - * "mapping": {"root": "uuid"}, + * "mapping": {"parent": "uuid"}, * "map_method_signature" = true, * } * ) @@ -194,8 +197,11 @@ public function browseToNodeAction(TeamStorageNode $teamStorageNode, DocumentNod * ) * @Template("KibokoDAMBundle:DocumentNode:update.html.twig") */ - public function createAction(Request $request, DocumentNodeInterface $parent,DocumentNodeInterface $root) - { + public function createAction( + Request $request, + DocumentNodeInterface $root, + DocumentNodeInterface $parent + ) { $node = new DocumentNode(); $node->setParent($parent); @@ -203,23 +209,28 @@ public function createAction(Request $request, DocumentNodeInterface $parent,Doc } /** - * * @param Request $request * @param DocumentNodeInterface $node * @param DocumentNodeInterface|null $root + * * @return array|Response * - * @Route("/{root}/update/{uuid}", + * @Route("/{root}/update/{node}", * name="kiboko_dam_node_update", - * requirements={"uuid"="[\da-f]{8}-[\da-f]{4}-[\da-f]{4}-[\da-f]{4}-[\da-f]{12}"} + * requirements={ + * "root"="[\da-f]{8}-[\da-f]{4}-[\da-f]{4}-[\da-f]{4}-[\da-f]{12}", + * "node"="[\da-f]{8}-[\da-f]{4}-[\da-f]{4}-[\da-f]{4}-[\da-f]{12}", + * } * ) * @ParamConverter("node", * class="KibokoDAMBundle:DocumentNode", * options={ - * "mapping": {"uuid": "uuid"}, + * "mapping": { + * "node": "uuid" + * }, * "map_method_signature" = true, * } - *) + * ) * @ParamConverter("root", * class="KibokoDAMBundle:DocumentNode", * options={ @@ -237,9 +248,9 @@ public function createAction(Request $request, DocumentNodeInterface $parent,Doc * ) * @Template("KibokoDAMBundle:DocumentNode:update.html.twig") */ - public function editAction(Request $request,DocumentNodeInterface $node, DocumentNodeInterface $root = null) + public function editAction(Request $request, DocumentNodeInterface $node, DocumentNodeInterface $root = null) { - return $this->update($request,$node,$root); + return $this->update($request, $node, $root); } /** @@ -249,7 +260,7 @@ public function editAction(Request $request,DocumentNodeInterface $node, Docume * * @return array|Response */ - private function update(Request $request,DocumentNodeInterface $node, DocumentNodeInterface $root = null) + private function update(Request $request, DocumentNodeInterface $node, DocumentNodeInterface $root = null) { return $this->handler->update( $node, diff --git a/src/DAMBundle/Controller/DocumentNodeTreeAjaxController.php b/src/DAMBundle/Controller/DocumentNodeTreeAjaxController.php index ddf6186..bfec85e 100644 --- a/src/DAMBundle/Controller/DocumentNodeTreeAjaxController.php +++ b/src/DAMBundle/Controller/DocumentNodeTreeAjaxController.php @@ -20,16 +20,21 @@ /** * @Route("/node/tree", service="kiboko_dam.controller.document_node_tree_ajax_controller") */ -class DocumentNodeTreeAjaxController extends Controller +final class DocumentNodeTreeAjaxController extends Controller { - - /** @var EntityManager */ + /** + * @var EntityManager + */ private $em; - /** @var LocalizationHelper */ + /** + * @var LocalizationHelper + */ private $localizationHelper; - /** @var DocumentNodeUpdateTreeHandler */ + /** + * @var DocumentNodeUpdateTreeHandler + */ private $handler; /** @@ -41,18 +46,18 @@ public function __construct( EntityManager $em, LocalizationHelper $localizationHelper, DocumentNodeUpdateTreeHandler $handler - ) { $this->em = $em; $this->localizationHelper = $localizationHelper; $this->handler = $handler; } - /** - * @Route("/delete/{uuid}", + * @Route("/delete/{node}", * name="kiboko_dam_document_node_tree_ajax_delete", - * requirements={"uuid"="[\da-f]{8}-[\da-f]{4}-[\da-f]{4}-[\da-f]{4}-[\da-f]{12}"}, + * requirements={ + * "node"="[\da-f]{8}-[\da-f]{4}-[\da-f]{4}-[\da-f]{4}-[\da-f]{12}" + * }, * options={ * "expose"=true, * }, @@ -61,7 +66,7 @@ public function __construct( * class="KibokoDAMBundle:DocumentNode", * options={ * "mapping": { - * "uuid": "uuid", + * "node": "uuid", * }, * "map_method_signature" = true, * } @@ -75,20 +80,19 @@ public function deleteAction(Request $request, DocumentNodeInterface $node) try { $this->em->remove($node); $this->em->flush(); - } - catch (ORMException $e) { + } catch (ORMException $e) { return new JsonResponse($e->getMessage(),500); - } return new JsonResponse('deleted',200); - } - /** - * @Route("/rename/{uuid}", + /** + * @Route("/rename/{node}", * name="kiboko_dam_document_node_tree_ajax_rename", - * requirements={"uuid"="[\da-f]{8}-[\da-f]{4}-[\da-f]{4}-[\da-f]{4}-[\da-f]{12}"}, + * requirements={ + * "node"="[\da-f]{8}-[\da-f]{4}-[\da-f]{4}-[\da-f]{4}-[\da-f]{12}" + * }, * options={ * "expose"=true, * }, @@ -97,7 +101,7 @@ public function deleteAction(Request $request, DocumentNodeInterface $node) * class="KibokoDAMBundle:DocumentNode", * options={ * "mapping": { - * "uuid": "uuid", + * "node": "uuid", * }, * "map_method_signature" = true, * } @@ -123,19 +127,18 @@ public function renameAction(Request $request, DocumentNodeInterface $node) try { $this->em->persist($node); $this->em->flush(); - } - catch (ORMException $e) { + } catch (ORMException $e) { return new JsonResponse($e->getMessage(),500); } return new JsonResponse('renamed',200); } - /** - * @Route("/create/{uuid}", + /** + * @Route("/create/{node}", * name="kiboko_dam_document_node_tree_ajax_create", * requirements={ - * "uuid"="[\da-f]{8}-[\da-f]{4}-[\da-f]{4}-[\da-f]{4}-[\da-f]{12}" + * "node"="[\da-f]{8}-[\da-f]{4}-[\da-f]{4}-[\da-f]{4}-[\da-f]{12}" * }, * options={ * "expose"=true, @@ -156,14 +159,16 @@ public function renameAction(Request $request, DocumentNodeInterface $node) */ public function createNodeAction(Request $request, DocumentNodeInterface $node) { - $name = $request->get('name'); - return $this->handler->createNode($node, $name); + return $this->handler->createNode($node, $request->request->get('name')); } /** - * @Route("/move/{uuid}/to/{uuidParent}", + * @Route("/move/{node}/to/{parent}", * name="kiboko_dam_document_node_tree_ajax_move", - * requirements={"uuid"="[\da-f]{8}-[\da-f]{4}-[\da-f]{4}-[\da-f]{4}-[\da-f]{12}"}, + * requirements={ + * "node"="[\da-f]{8}-[\da-f]{4}-[\da-f]{4}-[\da-f]{4}-[\da-f]{12}", + * "parent"="[\da-f]{8}-[\da-f]{4}-[\da-f]{4}-[\da-f]{4}-[\da-f]{12}", + * }, * options={ * "expose"=true, * }, @@ -172,7 +177,7 @@ public function createNodeAction(Request $request, DocumentNodeInterface $node) * class="KibokoDAMBundle:DocumentNode", * options={ * "mapping": { - * "uuid": "uuid", + * "node": "uuid", * }, * "map_method_signature" = true, * } @@ -181,7 +186,7 @@ public function createNodeAction(Request $request, DocumentNodeInterface $node) * class="KibokoDAMBundle:DocumentNode", * options={ * "mapping": { - * "uuidParent": "uuid", + * "parent": "uuid", * }, * "map_method_signature" = true, * } @@ -190,10 +195,8 @@ public function createNodeAction(Request $request, DocumentNodeInterface $node) * * {@inheritdoc} */ - public function moveAction(Request $request, MovableInterface $node,MovableInterface $newParent) + public function moveAction(MovableInterface $node, MovableInterface $newParent) { - return $this->handler->moveNode($node,$newParent); - + return $this->handler->moveNode($node, $newParent); } - } diff --git a/src/DAMBundle/Controller/TeamStorageNodeController.php b/src/DAMBundle/Controller/TeamStorageNodeController.php index b4dcbcb..33e6bfa 100644 --- a/src/DAMBundle/Controller/TeamStorageNodeController.php +++ b/src/DAMBundle/Controller/TeamStorageNodeController.php @@ -3,7 +3,6 @@ namespace Kiboko\Bundle\DAMBundle\Controller; use Kiboko\Bundle\DAMBundle\Entity\TeamStorageNode; -use Kiboko\Bundle\DAMBundle\JsTree\DocumentNodeUpdateTreeHandler; use Kiboko\Bundle\DAMBundle\Model\DocumentNodeInterface; use Oro\Bundle\FormBundle\Model\UpdateHandlerFacade; use Oro\Bundle\SecurityBundle\Annotation\Acl; @@ -36,7 +35,6 @@ final class TeamStorageNodeController extends Controller */ private $translator; - /** * @param Form $form * @param UpdateHandlerFacade $handler @@ -57,7 +55,6 @@ public function __construct( * * @Route("/", * name="kiboko_dam_index", - * requirements={"uuid"="[\da-f]{8}-[\da-f]{4}-[\da-f]{4}-[\da-f]{4}-[\da-f]{12}"} * ) * @Acl( * id="kiboko_dam_storage_view", @@ -97,15 +94,17 @@ public function createAction(Request $request) * * @return array|Response * - * @Route("/{uuid}/update", + * @Route("/{node}/update", * name="kiboko_dam_storage_update", - * requirements={"uuid"="[\da-f]{8}-[\da-f]{4}-[\da-f]{4}-[\da-f]{4}-[\da-f]{12}"}, + * requirements={ + * "node"="[\da-f]{8}-[\da-f]{4}-[\da-f]{4}-[\da-f]{4}-[\da-f]{12}" + * }, * ) * @ParamConverter("node", * class="KibokoDAMBundle:TeamStorageNode", * options={ * "mapping": { - * "uuid": "uuid", + * "node": "uuid", * }, * "map_method_signature" = true, * } diff --git a/src/DAMBundle/EventListener/DocumentDatagridListener.php b/src/DAMBundle/EventListener/DocumentDatagridListener.php index 0d94bc6..4729f58 100644 --- a/src/DAMBundle/EventListener/DocumentDatagridListener.php +++ b/src/DAMBundle/EventListener/DocumentDatagridListener.php @@ -4,11 +4,7 @@ use Doctrine\ORM\EntityManager; use Kiboko\Bundle\DAMBundle\Entity\DocumentNode; -use Oro\Bundle\DataGridBundle\Datasource\ResultRecordInterface; -use Oro\Bundle\DataGridBundle\Event\BuildAfter; use Oro\Bundle\DataGridBundle\Event\BuildBefore; -use Oro\Bundle\SecurityBundle\Tools\UUIDGenerator; - class DocumentDatagridListener { @@ -17,20 +13,17 @@ class DocumentDatagridListener */ private $em; - public function __construct( - EntityManager $em - ) { + public function __construct(EntityManager $em) + { $this->em = $em; } /** - * * @param BuildBefore $event */ public function onBuildBefore(BuildBefore $event) { - if( $event->getDatagrid()->getParameters()->get('_parameters')) - { + if ($event->getDatagrid()->getParameters()->get('_parameters')) { $uuid = $event->getDatagrid()->getParameters()->get('_parameters'); $uuid = $uuid['parent']; diff --git a/src/DAMBundle/EventListener/NavigationListener.php b/src/DAMBundle/EventListener/NavigationListener.php index e47536c..6240312 100644 --- a/src/DAMBundle/EventListener/NavigationListener.php +++ b/src/DAMBundle/EventListener/NavigationListener.php @@ -105,7 +105,7 @@ public function onNavigationConfigure(ConfigureMenuEvent $event) 'label' => $storage->getLocaleName($this->localizationHelper)->getString(), 'route' => 'kiboko_dam_node_browse', 'routeParameters' => [ - 'uuid' => $storage->getUuid()->toString(), + 'node' => $storage->getUuid()->toString(), ], ] ); @@ -158,7 +158,7 @@ private function buildStorageMenu(ItemInterface $storageItem, $storageData) 'label' => $storageLabel, 'route' => 'kiboko_dam_node_browse', 'routeParameters' => [ - 'uuid' => $storageId, + 'node' => $storageId, ], ] ); diff --git a/src/DAMBundle/Form/Type/DocumentNodeUuidType.php b/src/DAMBundle/Form/Type/DocumentNodeUuidType.php index 2fdd3b6..044e8d3 100644 --- a/src/DAMBundle/Form/Type/DocumentNodeUuidType.php +++ b/src/DAMBundle/Form/Type/DocumentNodeUuidType.php @@ -4,10 +4,7 @@ use DAMBundle\Form\DataTransformer\DocumentNodeUuidDataTransformer; use Kiboko\Bundle\DAMBundle\Entity\DocumentNode; -use Ramsey\Uuid\UuidFactory; -use Ramsey\Uuid\UuidInterface; use Symfony\Component\Form\AbstractType; -use Symfony\Component\Form\DataTransformerInterface; use Symfony\Component\Form\Extension\Core\Type\TextType; use Symfony\Component\Form\FormBuilderInterface; use Symfony\Component\OptionsResolver\OptionsResolver; diff --git a/src/DAMBundle/JsTree/DocumentNodeUpdateTreeHandler.php b/src/DAMBundle/JsTree/DocumentNodeUpdateTreeHandler.php index 84c93be..9dfd62b 100644 --- a/src/DAMBundle/JsTree/DocumentNodeUpdateTreeHandler.php +++ b/src/DAMBundle/JsTree/DocumentNodeUpdateTreeHandler.php @@ -215,8 +215,7 @@ public function createNode(DocumentNodeInterface $parent,string $name) { try { $this->entityManager->persist($node); $this->entityManager->flush(); - } - catch (ORMException $e) { + } catch (ORMException $e) { return new JsonResponse($e->getMessage(),500); } @@ -236,8 +235,7 @@ public function moveNode(MovableInterface $node, MovableInterface $newParent) try { $this->entityManager->persist($node); $this->entityManager->flush(); - } - catch (ORMException $e) { + } catch (ORMException $e) { return new JsonResponse($e->getMessage(),500); } diff --git a/src/DAMBundle/Resources/config/controllers.yml b/src/DAMBundle/Resources/config/controllers.yml index 742b6d0..d6ba6e8 100644 --- a/src/DAMBundle/Resources/config/controllers.yml +++ b/src/DAMBundle/Resources/config/controllers.yml @@ -28,3 +28,18 @@ services: - '@kiboko_dam.form.handler.document' - '@oro_ui.router' - '@session' + + kiboko_dam.controller.document_node: + class: Kiboko\Bundle\DAMBundle\Controller\DocumentNodeController + arguments: + - '@kiboko_dam.form.document_node' + - '@oro_form.update_handler' + - '@translator' + - '@kiboko_dam.tree.document_node_update_tree_handler' + + kiboko_dam.controller.team_storage: + class: Kiboko\Bundle\DAMBundle\Controller\TeamStorageNodeController + arguments: + - '@kiboko_dam.form.team_storage' + - '@oro_form.update_handler' + - '@translator' diff --git a/src/DAMBundle/Resources/config/services.yml b/src/DAMBundle/Resources/config/services.yml index ad4da34..c5a8842 100644 --- a/src/DAMBundle/Resources/config/services.yml +++ b/src/DAMBundle/Resources/config/services.yml @@ -43,15 +43,6 @@ services: - '@oro_locale.helper.localization' - '@doctrine.orm.entity_manager' - - kiboko_dam.controller.document_node: - class: Kiboko\Bundle\DAMBundle\Controller\DocumentNodeController - arguments: - - '@kiboko_dam.form.document_node' - - '@oro_form.update_handler' - - '@translator' - - '@kiboko_dam.tree.document_node_update_tree_handler' - kiboko_dam.form.type.team_storage: class: Kiboko\Bundle\DAMBundle\Form\Type\TeamStorageNodeType arguments: @@ -66,13 +57,6 @@ services: - 'kiboko_dam_document_form' - Kiboko\Bundle\DAMBundle\Form\Type\TeamStorageNodeType - kiboko_dam.controller.team_storage: - class: Kiboko\Bundle\DAMBundle\Controller\TeamStorageNodeController - arguments: - - '@kiboko_dam.form.team_storage' - - '@oro_form.update_handler' - - '@translator' - kiboko_dam.listener.navigation_listener: class: Kiboko\Bundle\DAMBundle\EventListener\NavigationListener arguments: diff --git a/src/DAMBundle/Resources/views/Document/update.html.twig b/src/DAMBundle/Resources/views/Document/update.html.twig index 90d034f..c95bbfe 100644 --- a/src/DAMBundle/Resources/views/Document/update.html.twig +++ b/src/DAMBundle/Resources/views/Document/update.html.twig @@ -5,7 +5,7 @@ {% set document = form.vars.value %} -{% set formAction = path('kiboko_dam_document_update', { 'uuid': document.uuid }) %} +{% set formAction = path('kiboko_dam_document_update', { 'node': document.uuid }) %} {% block navButtons %} @@ -13,7 +13,7 @@ {{ UI.cancelButton(path('kiboko_dam_index')) }} {% set html = UI.saveAndCloseButton({ 'route': 'kiboko_dam_node_browse', - 'params': {'uuid': '$uuid'} + 'params': { 'node': node.uuid } }) %} diff --git a/src/DAMBundle/Resources/views/Document/view.html.twig b/src/DAMBundle/Resources/views/Document/view.html.twig index c33aa38..554a587 100644 --- a/src/DAMBundle/Resources/views/Document/view.html.twig +++ b/src/DAMBundle/Resources/views/Document/view.html.twig @@ -7,7 +7,7 @@ {% block navButtons %} {% if is_granted('EDIT', entity) %} {{ UI.editButton({ - 'path' : path('kiboko_dam_document_update', { 'uuid': entity.uuid }), + 'path' : path('kiboko_dam_document_update', { 'node': entity.uuid }), 'entity_label': 'kiboko.dam.document.entity_label'|trans }) }} {% endif %} diff --git a/src/DAMBundle/Resources/views/DocumentNode/update.html.twig b/src/DAMBundle/Resources/views/DocumentNode/update.html.twig index c258e32..4790189 100644 --- a/src/DAMBundle/Resources/views/DocumentNode/update.html.twig +++ b/src/DAMBundle/Resources/views/DocumentNode/update.html.twig @@ -5,18 +5,18 @@ {% set node = form.vars.value %} {% if node.id %} - {% set formAction = path('kiboko_dam_node_update', { 'uuid': node.uuid }) %} + {% set formAction = path('kiboko_dam_node_update', { 'node': node.uuid }) %} {% else %} - {% set formAction = path('kiboko_dam_node_create', { 'uuid': node.parent.uuid, 'root': node.parent.uuid }) %} + {% set formAction = path('kiboko_dam_node_create', { 'parent': node.uuid, 'root': node.root.uuid }) %} {% endif %} {% block navButtons %} - {{ UI.cancelButton(path('kiboko_dam_node_browse', {uuid: node.uuid})) }} + {{ UI.cancelButton(path('kiboko_dam_node_browse', { node: node.uuid})) }} {% set html = UI.saveAndCloseButton({ 'route': 'kiboko_dam_node_browse', - 'params': {uuid: root.uuid} + 'params': { node: root.uuid } }) %} {{ UI.dropdownSaveButton({'html': html}) }} diff --git a/src/DAMBundle/Resources/views/TeamStorageNode/browse.html.twig b/src/DAMBundle/Resources/views/TeamStorageNode/browse.html.twig index fa37c7f..20c9d9b 100644 --- a/src/DAMBundle/Resources/views/TeamStorageNode/browse.html.twig +++ b/src/DAMBundle/Resources/views/TeamStorageNode/browse.html.twig @@ -9,7 +9,7 @@
{% if is_granted('kiboko_dam_node_create') %} {{ UI.addButton({ - 'path': path('kiboko_dam_node_create', { uuid: node.uuid }), + 'path': path('kiboko_dam_node_create', { node: node.uuid }), 'entity_label': 'kiboko.dam.views.teamstoragenode.browse.entity.label'|trans, }) }} {% endif %} diff --git a/src/DAMBundle/Resources/views/TeamStorageNode/update.html.twig b/src/DAMBundle/Resources/views/TeamStorageNode/update.html.twig index f8f5411..cead7eb 100644 --- a/src/DAMBundle/Resources/views/TeamStorageNode/update.html.twig +++ b/src/DAMBundle/Resources/views/TeamStorageNode/update.html.twig @@ -6,18 +6,17 @@ {% set node = form.vars.value %} {% if node.id %} - {% set formAction = path('kiboko_dam_storage_update', { 'uuid': node.uuid }) %} + {% set formAction = path('kiboko_dam_storage_update', { 'node': node.uuid }) %} {% else %} {% set formAction = path('kiboko_dam_storage_create') %} {% endif %} {% block navButtons %} - {{ UI.cancelButton(path('kiboko_dam_index')) }} {% set html = UI.saveAndCloseButton({ 'route': 'kiboko_dam_node_browse', - 'params': {'uuid': '$uuid'} + 'params': {'node': node.uuid} }) %} diff --git a/src/DAMBundle/Resources/views/tree/view.html.twig b/src/DAMBundle/Resources/views/tree/view.html.twig index 1d90ae0..02be317 100644 --- a/src/DAMBundle/Resources/views/tree/view.html.twig +++ b/src/DAMBundle/Resources/views/tree/view.html.twig @@ -19,7 +19,7 @@
{{ resetButton({ - 'dataUrl': path(routePrefix ~ 'ajax_reset', { uuid: entity.uuid }), + 'dataUrl': path(routePrefix ~ 'ajax_reset', { node: entity.uuid }), 'dataRedirect': path(routePrefix ~ 'view', { node: entity.uuid }), 'menuKey': entity.uuid, 'data': { @@ -30,7 +30,7 @@ {{ UI.buttonSeparator() }} {% set html = UI.button({ - 'path' : path(routePrefix ~ 'create', { uuid: entity.uuid }), + 'path' : path(routePrefix ~ 'create', { node: entity.uuid }), 'aCss': 'btn-primary', 'label': 'oro.ui.create_entity'|trans({ '%entityName%': 'kiboko.dam.documentnode.entity_label'|trans }), 'title': 'oro.ui.create_entity'|trans({ '%entityName%': 'kiboko.dam.documentnode.entity_label'|trans }) @@ -42,7 +42,7 @@ 'title': 'kiboko.dam.updload'|trans({ '%entityName%': 'kiboko.dam.document.entity_label'|trans }), 'dataMethod': 'POST', 'dataRedirect': app.request.uri, - 'dataUrl': path(routePrefix ~ 'ajax_create', { uuid: entity.uuid, parentKey: entity.names|localized_value, 'isDivider': true }), + 'dataUrl': path(routePrefix ~ 'ajax_create', { node: entity.uuid, parent: entity.names|localized_value, 'isDivider': true }), 'successMessage': dividerCreatedMessage|default('kiboko.dam.documentnode.divider_created')|trans({'%reload_link%': reloadLink}) }) %} @@ -51,7 +51,7 @@ 'title': 'kiboko.dam.updload_batch'|trans({ '%entityName%': 'kiboko.dam.document.entity_plural_label'|trans }), 'dataMethod': 'POST', 'dataRedirect': app.request.uri, - 'dataUrl': path(routePrefix ~ 'ajax_create', { uuid: entity.uuid, parentKey: entity.names|localized_value, 'isDivider': true }), + 'dataUrl': path(routePrefix ~ 'ajax_create', { node: entity.uuid, parent: entity.names|localized_value, 'isDivider': true }), 'successMessage': dividerCreatedMessage|default('kiboko.dam.documentnode.divider_created')|trans({'%reload_link%': reloadLink}) }) %} @@ -96,7 +96,7 @@ 'move': { 'view': 'oroui/js/app/views/jstree/move-action-view', 'routeName': routePrefix ~ 'move', - 'routeParams': { uuid: entity.uuid } + 'routeParams': { node: entity.uuid } } } ) }} diff --git a/src/DAMBundle/Tests/Functional/Controller/DocumentNodeTreeAjaxControllerTest.php b/src/DAMBundle/Tests/Functional/Controller/DocumentNodeTreeAjaxControllerTest.php new file mode 100644 index 0000000..1890275 --- /dev/null +++ b/src/DAMBundle/Tests/Functional/Controller/DocumentNodeTreeAjaxControllerTest.php @@ -0,0 +1,29 @@ +request('GET', '/dam/'); + + $this->assertEquals(200, $client->getResponse()->getStatusCode()); + } + + public function testCreateAction() + { + } + + public function testResetAction() + { + } + + public function testMoveAction() + { + } +} From d312817c7de96ec6837eee911161420f4812666a Mon Sep 17 00:00:00 2001 From: xavier Date: Thu, 17 Jan 2019 12:45:11 +0100 Subject: [PATCH 31/42] Customize document view with file info --- .../Resources/views/Document/view.html.twig | 22 ++++++++++++++++--- 1 file changed, 19 insertions(+), 3 deletions(-) diff --git a/src/DAMBundle/Resources/views/Document/view.html.twig b/src/DAMBundle/Resources/views/Document/view.html.twig index c33aa38..91771fc 100644 --- a/src/DAMBundle/Resources/views/Document/view.html.twig +++ b/src/DAMBundle/Resources/views/Document/view.html.twig @@ -1,6 +1,5 @@ {% extends 'OroUIBundle:actions:view.html.twig' %} {% import 'OroUIBundle::macros.html.twig' as UI %} -{% import 'OroDataGridBundle::macros.html.twig' as dataGrid %} {% oro_title_set({params : {"%document.name%": entity.names|localized_value} }) %} @@ -27,7 +26,13 @@ {% set info %} {{ UI.renderProperty('kiboko.dam.document.datagrid.columns.owner.label'|trans, entity.owner.username) }} {{ UI.renderProperty('kiboko.dam.document.datagrid.columns.name.label'|trans, entity.names|localized_value) }} - {{ UI.renderProperty('kiboko.dam.document.datagrid.columns.slug.label'|trans, entity.file.file) }} + {{ UI.renderProperty('kiboko.dam.document.datagrid.columns.slug.label'|trans, entity.slugs|localized_value) }} + {% endset %} + + {% set fileData %} + {{ UI.renderProperty('oro.attachment.file.file.label'|trans, entity.file.filename) }} + {{ UI.renderProperty('oro.attachment.file.extension.label'|trans, entity.file.extension) }} + {{ UI.renderProperty('oro.attachment.file.file_size.label'|trans, entity.file.filesize) }} {% endset %} {% set info = [ @@ -36,9 +41,20 @@ 'class': 'active', 'subblocks': [ - { 'data': [ info ] }, + { + 'data': [ info ] + }, ] }, + { + 'title': 'oro.attachment.file.entity_label'|trans, + 'subblocks': + [ + { + 'data': [ fileData ] + }, + ] + } ] %} {% set id = 'editorialView' %} From 8899c4b427434554eb15ee8a83485ea6226ffcb9 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Gr=C3=A9gory=20Planchat?= Date: Thu, 17 Jan 2019 15:24:10 +0100 Subject: [PATCH 32/42] Fixed Node browsing --- .../Controller/AssetWidgetController.php | 8 +- .../Controller/DocumentController.php | 4 +- .../Controller/DocumentNodeController.php | 60 +++--------- src/DAMBundle/Entity/TeamStorageNode.php | 2 +- .../EventListener/NavigationListener.php | 14 ++- .../Resources/config/oro/datagrids.yml | 4 + .../public/js/app/views/tree-manage-view.js | 4 +- .../Resources/translations/messages.fr_FR.yml | 98 +++++++++---------- .../Resources/views/Document/update.html.twig | 3 +- .../views/DocumentNode/browse.html.twig | 2 +- .../views/DocumentNode/update.html.twig | 6 +- .../views/TeamStorageNode/update.html.twig | 2 +- 12 files changed, 94 insertions(+), 113 deletions(-) diff --git a/src/DAMBundle/Controller/AssetWidgetController.php b/src/DAMBundle/Controller/AssetWidgetController.php index d7fd28a..8d81971 100644 --- a/src/DAMBundle/Controller/AssetWidgetController.php +++ b/src/DAMBundle/Controller/AssetWidgetController.php @@ -93,7 +93,9 @@ public function __construct( * @ParamConverter("node", * class="KibokoDAMBundle:DocumentNode", * options={ - * "mapping": {"node": "uuid"}, + * "mapping": { + * "node": "uuid" + * }, * "map_method_signature" = true, * } * ) @@ -130,7 +132,9 @@ public function widgetAction(DocumentNodeInterface $node) * @ParamConverter("node", * class="KibokoDAMBundle:DocumentNode", * options={ - * "mapping": {"node": "uuid"}, + * "mapping": { + * "node": "uuid" + * }, * "map_method_signature" = true, * } * ) diff --git a/src/DAMBundle/Controller/DocumentController.php b/src/DAMBundle/Controller/DocumentController.php index 033a7ec..95e07d1 100644 --- a/src/DAMBundle/Controller/DocumentController.php +++ b/src/DAMBundle/Controller/DocumentController.php @@ -90,7 +90,9 @@ public function __construct( * @ParamConverter("node", * class="KibokoDAMBundle:DocumentNode", * options={ - * "mapping": {"node": "uuid"}, + * "mapping": { + * "node": "uuid" + * }, * "map_method_signature" = true, * } * ) diff --git a/src/DAMBundle/Controller/DocumentNodeController.php b/src/DAMBundle/Controller/DocumentNodeController.php index 18d0cce..62b9276 100644 --- a/src/DAMBundle/Controller/DocumentNodeController.php +++ b/src/DAMBundle/Controller/DocumentNodeController.php @@ -61,60 +61,24 @@ public function __construct( $this->treeHandler = $treeHandler; } - /** - * @param TeamStorageNode $node - * - * @return array|Response - * - * @Route("/{node}/browse", - * name="kiboko_dam_node_browse", - * requirements={"node"="[\da-f]{8}-[\da-f]{4}-[\da-f]{4}-[\da-f]{4}-[\da-f]{12}"} - * ) - * @ParamConverter("node", - * class="KibokoDAMBundle:TeamStorageNode", - * options={ - * "mapping": { - * "node": "uuid", - * }, - * "map_method_signature" = true, - * } - * ) - * @Acl( - * id="kiboko_dam_node_view", - * type="entity", - * class="KibokoDAMBundle:DocumentNode", - * permission="VIEW" - * ) - * @Template() - */ - public function browseAction(TeamStorageNode $node) - { - $path = []; - $parent = $node; - while (($parent = $parent->getParent()) !== null) { - $path[] = $parent; - } - - return [ - 'teamstorage' => $node, - 'path' => $path, - 'tree' => $this->treeHandler->createTree($node), - ]; - } - /** * @param TeamStorageNode $root * @param DocumentNode $node * * @return array|Response - * * @Route("/{root}/browse/{node}", - * name="kiboko_dam_node_browse_to_node", + * name="kiboko_dam_node_browse", * requirements={ * "root"="[\da-f]{8}-[\da-f]{4}-[\da-f]{4}-[\da-f]{4}-[\da-f]{12}", * "node"="[\da-f]{8}-[\da-f]{4}-[\da-f]{4}-[\da-f]{4}-[\da-f]{12}" * } * ) + * @Route("/{root}/browse", + * name="kiboko_dam_root_browse", + * requirements={ + * "root"="[\da-f]{8}-[\da-f]{4}-[\da-f]{4}-[\da-f]{4}-[\da-f]{12}", + * } + * ) * @ParamConverter("root", * class="KibokoDAMBundle:TeamStorageNode", * options={ @@ -141,7 +105,7 @@ public function browseAction(TeamStorageNode $node) * ) * @Template("@KibokoDAM/DocumentNode/browse.html.twig") */ - public function browseToNodeAction(TeamStorageNode $root, DocumentNode $node) + public function browseAction(TeamStorageNode $root, ?DocumentNode $node = null) { $path = []; $parent = $root; @@ -178,14 +142,18 @@ public function browseToNodeAction(TeamStorageNode $root, DocumentNode $node) * @ParamConverter("root", * class="KibokoDAMBundle:DocumentNode", * options={ - * "mapping": {"root": "uuid"}, + * "mapping": { + * "root": "uuid" + * }, * "map_method_signature" = true, * } * ) * @ParamConverter("parent", * class="KibokoDAMBundle:DocumentNode", * options={ - * "mapping": {"parent": "uuid"}, + * "mapping": { + * "parent": "uuid" + * }, * "map_method_signature" = true, * } * ) diff --git a/src/DAMBundle/Entity/TeamStorageNode.php b/src/DAMBundle/Entity/TeamStorageNode.php index f273444..b04d2e3 100644 --- a/src/DAMBundle/Entity/TeamStorageNode.php +++ b/src/DAMBundle/Entity/TeamStorageNode.php @@ -10,7 +10,7 @@ /** * @ORM\Entity(repositoryClass="Kiboko\Bundle\DAMBundle\Repository\TeamStorageNodeRepository") * @Config( - * routeName="kiboko_dam_node_browse", + * routeName="kiboko_dam_root_browse", * routeCreate="kiboko_dam_storage_create", * routeUpdate="kiboko_dam_storage_update", * defaultValues={ diff --git a/src/DAMBundle/EventListener/NavigationListener.php b/src/DAMBundle/EventListener/NavigationListener.php index 6240312..e5027b7 100644 --- a/src/DAMBundle/EventListener/NavigationListener.php +++ b/src/DAMBundle/EventListener/NavigationListener.php @@ -2,6 +2,7 @@ namespace Kiboko\Bundle\DAMBundle\EventListener; +use Doctrine\ORM\Query; use Kiboko\Bundle\DAMBundle\Entity\DocumentNode; use Kiboko\Bundle\DAMBundle\Model\DocumentNodeInterface; use Kiboko\Bundle\DAMBundle\Repository\DocumentNodeRepository; @@ -91,8 +92,11 @@ public function onNavigationConfigure(ConfigureMenuEvent $event) ->getEntityRepositoryForClass(DocumentNode::class); $qb = $repository->getRootNodesQueryBuilder(); + /** @var Query $query */ + $query = $this->aclHelper->apply($qb); + /** @var DocumentNodeInterface[] $storages */ - $storages = $this->aclHelper->apply($qb)->getResult(); + $storages = $query->getResult(); if (!$storages) { return; } @@ -103,9 +107,9 @@ public function onNavigationConfigure(ConfigureMenuEvent $event) 'kiboko_dam_storage_' . $storage->getUuid()->toString(), [ 'label' => $storage->getLocaleName($this->localizationHelper)->getString(), - 'route' => 'kiboko_dam_node_browse', + 'route' => 'kiboko_dam_root_browse', 'routeParameters' => [ - 'node' => $storage->getUuid()->toString(), + 'root' => $storage->getUuid()->toString(), ], ] ); @@ -156,9 +160,9 @@ private function buildStorageMenu(ItemInterface $storageItem, $storageData) $storageLabel . '_report', [ 'label' => $storageLabel, - 'route' => 'kiboko_dam_node_browse', + 'route' => 'kiboko_dam_root_browse', 'routeParameters' => [ - 'node' => $storageId, + 'root' => $storageId, ], ] ); diff --git a/src/DAMBundle/Resources/config/oro/datagrids.yml b/src/DAMBundle/Resources/config/oro/datagrids.yml index 4e79a73..c401816 100644 --- a/src/DAMBundle/Resources/config/oro/datagrids.yml +++ b/src/DAMBundle/Resources/config/oro/datagrids.yml @@ -49,6 +49,7 @@ datagrids: query: select: - node.uuid + - node.root.uuid AS root - name.string AS localeName - slug.string AS localeSlug - channel.name AS integration @@ -70,6 +71,7 @@ datagrids: type: url route: kiboko_dam_node_browse params: + root: root uuid: uuid update_link: type: url @@ -84,6 +86,7 @@ datagrids: query: select: - node.uuid + - node.root.uuid AS root - name.string AS localeName - slug.string AS localeSlug from: @@ -105,6 +108,7 @@ datagrids: type: url route: kiboko_dam_node_browse params: + root: root uuid: uuid update_link: type: url diff --git a/src/DAMBundle/Resources/public/js/app/views/tree-manage-view.js b/src/DAMBundle/Resources/public/js/app/views/tree-manage-view.js index 5b0ae25..347ff2d 100644 --- a/src/DAMBundle/Resources/public/js/app/views/tree-manage-view.js +++ b/src/DAMBundle/Resources/public/js/app/views/tree-manage-view.js @@ -241,12 +241,12 @@ define(function (require) { let url; if (this.onRootSelectRoute && selected.node.parent === '#') { url = routing.generate(this.onRootSelectRoute, { - storage: selected.node.original.storage, + root: selected.node.original.storage, node: selected.node.original.uuid }); } else { url = routing.generate(this.onSelectRoute, { - storage: selected.node.original.storage, + root: selected.node.original.storage, node: selected.node.original.uuid }); } diff --git a/src/DAMBundle/Resources/translations/messages.fr_FR.yml b/src/DAMBundle/Resources/translations/messages.fr_FR.yml index 8db1d5c..38d6c79 100644 --- a/src/DAMBundle/Resources/translations/messages.fr_FR.yml +++ b/src/DAMBundle/Resources/translations/messages.fr_FR.yml @@ -1,60 +1,60 @@ kiboko: dam: teamstoragenode: - entity_label: Stockage d'équipe - entity_plural_label: Stockages d'équipe + entity_label: "Stockage d'équipe" + entity_plural_label: "Stockages d'équipe" owner: - label: Propriétaire + label: "Propriétaire" message: - success: Le stockage d'équipe a bien été déclaré + success: "Le stockage d'équipe a bien été déclaré" documentnode: - entity_label: Dossier - create_label: 'Créer un %entityName%' - entity_plural_label: Dossiers - reset: Reset - empty_node: Ce dossier est vide, de nouvequx fichiers apparaitront une fois que vous aurez envoyé de nouveaux fichiers par lots. - datagrid: - columns: - name: - label: Nom - slug: - label: Url slug - integration: - label: Integration - create_label: Créer un dossier - divider_created: Diviseur - updated: - label: 'Document mis à jour' - owner: - label: Propriétaire - document: + entity_label: "Dossier" + create_label: "Créer un %entityName%" + entity_plural_label: "Dossiers" + reset: "Reset" + empty_node: "Ce dossier est vide, de nouvequx fichiers apparaitront une fois que vous aurez envoyé de nouveaux fichiers par lots." + datagrid: + columns: + name: + label: "Nom" + slug: + label: "Url slug" + integration: + label: "Integration" + create_label: "Créer un dossier" + divider_created: "Diviseur" + updated: + label: "Document mis à jour" + owner: + label: "Propriétaire" + document: + owner: + label: "Propriétaire" + entity_label: "Ressource" + create_label: "Téléverser" + entity_plural_label: "Ressource" + datagrid: + columns: + name: + label: "Nom" + slug: + label: "Url slug" owner: - label: Propriétaire - entity_label: Ressource - create_label: Téléverser - entity_plural_label: Ressource - datagrid: - columns: - name: - label: Nom - slug: - label: Url slug - owner: - label: Propriétaire - thumbnail: - label: Vignette - extension: - label: Extension - filesize: - label: Taille - createdat: - label: Créer le - updatedat: - label: Mis à jour le - upload: - ok: - label: 'Document téléversé' + label: "Propriétaire" + thumbnail: + label: "Vignette" + extension: + label: "Extension" + filesize: + label: "Taille" + createdat: + label: "Créer le" + updatedat: + label: "Mis à jour le" + upload: + ok: + label: "Document téléversé" updload: 'Envoyer un %entityName%' updload_batch: 'Envoyer des %entityName% par lot' diff --git a/src/DAMBundle/Resources/views/Document/update.html.twig b/src/DAMBundle/Resources/views/Document/update.html.twig index c95bbfe..bccf1ff 100644 --- a/src/DAMBundle/Resources/views/Document/update.html.twig +++ b/src/DAMBundle/Resources/views/Document/update.html.twig @@ -13,10 +13,9 @@ {{ UI.cancelButton(path('kiboko_dam_index')) }} {% set html = UI.saveAndCloseButton({ 'route': 'kiboko_dam_node_browse', - 'params': { 'node': node.uuid } + 'params': { 'root': node.root.uuid, 'node': node.uuid } }) %} - {{ UI.dropdownSaveButton({'html': html}) }} {% endblock navButtons %} diff --git a/src/DAMBundle/Resources/views/DocumentNode/browse.html.twig b/src/DAMBundle/Resources/views/DocumentNode/browse.html.twig index 29aa33a..ba7a6c0 100644 --- a/src/DAMBundle/Resources/views/DocumentNode/browse.html.twig +++ b/src/DAMBundle/Resources/views/DocumentNode/browse.html.twig @@ -101,7 +101,7 @@ 'nodeId': teamstorage.uuid, 'updateAllowed' : true, 'view' : 'kibokodam/js/app/views/tree-manage-view', - 'onRootSelectRoute' : routePrefix ~ 'view', + 'onRootSelectRoute' : routePrefix ~ 'browse', 'onSelectRoute' : routePrefix ~ 'update', 'onMoveRoute' : routePrefix ~ 'move', 'successMessage': movedMessage|default('oro.navigation.menuupdate.moved_success_message') diff --git a/src/DAMBundle/Resources/views/DocumentNode/update.html.twig b/src/DAMBundle/Resources/views/DocumentNode/update.html.twig index 4790189..b8557b1 100644 --- a/src/DAMBundle/Resources/views/DocumentNode/update.html.twig +++ b/src/DAMBundle/Resources/views/DocumentNode/update.html.twig @@ -12,11 +12,11 @@ {% block navButtons %} - {{ UI.cancelButton(path('kiboko_dam_node_browse', { node: node.uuid})) }} + {{ UI.cancelButton(path('kiboko_dam_node_browse', { root: node.root.uuid, node: node.uuid})) }} {% set html = UI.saveAndCloseButton({ - 'route': 'kiboko_dam_node_browse', - 'params': { node: root.uuid } + 'route': 'kiboko_dam_root_browse', + 'params': { root: root.uuid } }) %} {{ UI.dropdownSaveButton({'html': html}) }} diff --git a/src/DAMBundle/Resources/views/TeamStorageNode/update.html.twig b/src/DAMBundle/Resources/views/TeamStorageNode/update.html.twig index cead7eb..47005a4 100644 --- a/src/DAMBundle/Resources/views/TeamStorageNode/update.html.twig +++ b/src/DAMBundle/Resources/views/TeamStorageNode/update.html.twig @@ -16,7 +16,7 @@ {{ UI.cancelButton(path('kiboko_dam_index')) }} {% set html = UI.saveAndCloseButton({ 'route': 'kiboko_dam_node_browse', - 'params': {'node': node.uuid} + 'params': { 'root': node.root.uuid, 'node': node.uuid } }) %} From e7a96ff4990d8a2813178e4bb413d404420b4cec Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Gr=C3=A9gory=20Planchat?= Date: Thu, 17 Jan 2019 15:42:31 +0100 Subject: [PATCH 33/42] Added root node accessor on root nodes --- src/DAMBundle/Entity/DocumentNode.php | 8 ++++++++ 1 file changed, 8 insertions(+) diff --git a/src/DAMBundle/Entity/DocumentNode.php b/src/DAMBundle/Entity/DocumentNode.php index 31838bc..3ee8e1c 100644 --- a/src/DAMBundle/Entity/DocumentNode.php +++ b/src/DAMBundle/Entity/DocumentNode.php @@ -306,6 +306,14 @@ public function setUuid(UuidInterface $uuid): void $this->uuid = $uuid; } + /** + * @return DocumentNodeInterface + */ + public function getRoot(): DocumentNodeInterface + { + return $this->root; + } + /** * @return UserInterface */ From a6edc811f2dee9c5690a00224e6b0ebdf26de07c Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Gr=C3=A9gory=20Planchat?= Date: Thu, 17 Jan 2019 15:44:38 +0100 Subject: [PATCH 34/42] Fixed datagrids URL generation --- src/DAMBundle/Resources/config/oro/datagrids.yml | 11 +++++------ 1 file changed, 5 insertions(+), 6 deletions(-) diff --git a/src/DAMBundle/Resources/config/oro/datagrids.yml b/src/DAMBundle/Resources/config/oro/datagrids.yml index c401816..dfad853 100644 --- a/src/DAMBundle/Resources/config/oro/datagrids.yml +++ b/src/DAMBundle/Resources/config/oro/datagrids.yml @@ -49,7 +49,6 @@ datagrids: query: select: - node.uuid - - node.root.uuid AS root - name.string AS localeName - slug.string AS localeSlug - channel.name AS integration @@ -69,15 +68,14 @@ datagrids: uuid: ~ view_link: type: url - route: kiboko_dam_node_browse + route: kiboko_dam_root_browse params: - root: root - uuid: uuid + root: uuid update_link: type: url route: kiboko_dam_storage_update params: - uuid: uuid + node: uuid kiboko-dam-document-nodes-grid: extends: kiboko-dam-nodes-grid @@ -86,7 +84,7 @@ datagrids: query: select: - node.uuid - - node.root.uuid AS root + - root.uuid AS root - name.string AS localeName - slug.string AS localeSlug from: @@ -95,6 +93,7 @@ datagrids: left: - { join: node.names, alias: name } - { join: node.slugs, alias: slug } + - { join: node.root, alias: root } where: and: - name.localization IS NULL From 1b24f031c16ec38364e07261c0ec528be0d8a9e6 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Gr=C3=A9gory=20Planchat?= Date: Thu, 17 Jan 2019 15:53:56 +0100 Subject: [PATCH 35/42] Fixed tree URL generation --- src/DAMBundle/Controller/DocumentNodeController.php | 10 ++++++++++ .../Resources/public/js/app/views/tree-manage-view.js | 3 +-- .../Resources/views/DocumentNode/browse.html.twig | 6 +++--- .../Resources/views/TeamStorageNode/browse.html.twig | 2 +- 4 files changed, 15 insertions(+), 6 deletions(-) diff --git a/src/DAMBundle/Controller/DocumentNodeController.php b/src/DAMBundle/Controller/DocumentNodeController.php index 62b9276..7214b4a 100644 --- a/src/DAMBundle/Controller/DocumentNodeController.php +++ b/src/DAMBundle/Controller/DocumentNodeController.php @@ -139,6 +139,16 @@ public function browseAction(TeamStorageNode $root, ?DocumentNode $node = null) * "expose"=true, * } * ) + * @Route("/{root}/create", + * name="kiboko_dam_node_create", + * requirements={ + * "root"="[\da-f]{8}-[\da-f]{4}-[\da-f]{4}-[\da-f]{4}-[\da-f]{12}", + * "parent"="[\da-f]{8}-[\da-f]{4}-[\da-f]{4}-[\da-f]{4}-[\da-f]{12}" + * }, + * options={ + * "expose"=true, + * } + * ) * @ParamConverter("root", * class="KibokoDAMBundle:DocumentNode", * options={ diff --git a/src/DAMBundle/Resources/public/js/app/views/tree-manage-view.js b/src/DAMBundle/Resources/public/js/app/views/tree-manage-view.js index 347ff2d..cd037a3 100644 --- a/src/DAMBundle/Resources/public/js/app/views/tree-manage-view.js +++ b/src/DAMBundle/Resources/public/js/app/views/tree-manage-view.js @@ -69,9 +69,8 @@ define(function (require) { * @param nodeUuid */ refreshButtonsRoute: function (nodeUuid) { - this.createNodeWidget.attr('href', routing.generate('kiboko_dam_node_create', { - 'uuid': nodeUuid, + 'parent': nodeUuid, 'root': this.rootUuid })); diff --git a/src/DAMBundle/Resources/views/DocumentNode/browse.html.twig b/src/DAMBundle/Resources/views/DocumentNode/browse.html.twig index ba7a6c0..88a61c3 100644 --- a/src/DAMBundle/Resources/views/DocumentNode/browse.html.twig +++ b/src/DAMBundle/Resources/views/DocumentNode/browse.html.twig @@ -31,7 +31,7 @@
{{ UI.button({ - 'path' : path(routePrefix ~ 'create' , { uuid: teamstorage.uuid, root: teamstorage.uuid}), + 'path' : path(routePrefix ~ 'create' , { parent: teamstorage.uuid, root: teamstorage.uuid}), 'iCss': 'fa-folder', 'label': 'kiboko.dam.documentnode.create_label'|trans({ '%entityName%': 'kiboko.dam.documentnode.entity_label'|trans }), 'title': 'kiboko.dam.documentnode.create_label'|trans({ '%entityName%': 'kiboko.dam.documentnode.entity_label'|trans }) @@ -41,7 +41,7 @@ {# Create Divider button #} {% set html = UI.clientButton({ - 'dataUrl': path('kiboko_dam_upload_asset_widget', { uuid: teamstorage.uuid}), + 'dataUrl': path('kiboko_dam_upload_asset_widget', { node: teamstorage.uuid}), 'aCss': 'btn-primary upload_button_widget', 'iCss': 'fa-image', 'label': 'kiboko.dam.updload'|trans({ '%entityName%': 'kiboko.dam.document.entity_label'|trans }), @@ -71,7 +71,7 @@ 'iCss': 'fa-plus', 'dataMethod': 'POST', 'dataRedirect': app.request.uri, - 'dataUrl': path(routePrefix ~ 'create', { uuid: teamstorage.uuid, parentKey: teamstorage.names|localized_value, 'isDivider': true, root: teamstorage.uuid }), + 'dataUrl': path(routePrefix ~ 'create', { parent: teamstorage.uuid, parentKey: teamstorage.names|localized_value, 'isDivider': true, root: teamstorage.uuid }), 'successMessage': dividerCreatedMessage|default('kiboko.dam.documentnode.divider_created')|trans({'%reload_link%': reloadLink}) }) %} diff --git a/src/DAMBundle/Resources/views/TeamStorageNode/browse.html.twig b/src/DAMBundle/Resources/views/TeamStorageNode/browse.html.twig index 20c9d9b..9e42696 100644 --- a/src/DAMBundle/Resources/views/TeamStorageNode/browse.html.twig +++ b/src/DAMBundle/Resources/views/TeamStorageNode/browse.html.twig @@ -9,7 +9,7 @@
{% if is_granted('kiboko_dam_node_create') %} {{ UI.addButton({ - 'path': path('kiboko_dam_node_create', { node: node.uuid }), + 'path': path('kiboko_dam_node_create', { parent: node.uuid, root: node.root.uuid }), 'entity_label': 'kiboko.dam.views.teamstoragenode.browse.entity.label'|trans, }) }} {% endif %} From df7d50878f18868a1b65e2c4ac04c36d5df47db7 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Gr=C3=A9gory=20Planchat?= Date: Thu, 17 Jan 2019 16:01:09 +0100 Subject: [PATCH 36/42] Fixed js URL generation --- src/DAMBundle/Resources/config/oro/datagrids.yml | 4 ++-- .../Resources/public/js/app/views/tree-manage-view.js | 10 +++++----- 2 files changed, 7 insertions(+), 7 deletions(-) diff --git a/src/DAMBundle/Resources/config/oro/datagrids.yml b/src/DAMBundle/Resources/config/oro/datagrids.yml index dfad853..6603481 100644 --- a/src/DAMBundle/Resources/config/oro/datagrids.yml +++ b/src/DAMBundle/Resources/config/oro/datagrids.yml @@ -108,12 +108,12 @@ datagrids: route: kiboko_dam_node_browse params: root: root - uuid: uuid + node: uuid update_link: type: url route: kiboko_dam_node_update params: - uuid: uuid + node: uuid kiboko-dam-documents-grid: options: diff --git a/src/DAMBundle/Resources/public/js/app/views/tree-manage-view.js b/src/DAMBundle/Resources/public/js/app/views/tree-manage-view.js index cd037a3..12479b5 100644 --- a/src/DAMBundle/Resources/public/js/app/views/tree-manage-view.js +++ b/src/DAMBundle/Resources/public/js/app/views/tree-manage-view.js @@ -116,7 +116,7 @@ define(function (require) { onNodeDelete: function (e, data) { var uuid = data.node.original.uuid; - var url = routing.generate('kiboko_dam_document_node_tree_ajax_delete', {uuid: uuid}); + var url = routing.generate('kiboko_dam_document_node_tree_ajax_delete', {node: uuid}); $.ajax({ async: true, @@ -165,8 +165,8 @@ define(function (require) { if (uuid !== uuidParent) { var url = routing.generate('kiboko_dam_document_node_tree_ajax_move', { - uuid: uuid, - uuidParent: uuidParent + node: uuid, + parent: uuidParent }); $.ajax({ async: true, @@ -189,7 +189,7 @@ define(function (require) { if (uuid) { var name = data.text; if (data.node.original.uuid !== '') { - var url = routing.generate('kiboko_dam_document_node_tree_ajax_rename', {uuid: uuid}); + var url = routing.generate('kiboko_dam_document_node_tree_ajax_rename', {node: uuid}); $.ajax({ async: true, type: 'POST', @@ -213,7 +213,7 @@ define(function (require) { var name = data.node.original.text; if (data.node.original.uuid !== '') { - var url = routing.generate('kiboko_dam_document_node_tree_ajax_create', {uuid: this.formatUuuid(parent)}); + var url = routing.generate('kiboko_dam_document_node_tree_ajax_create', {node: this.formatUuuid(parent)}); $.ajax({ type: 'POST', data: { From 6153ffbfb8e786c90cb1fa09f9777fac392ad1d5 Mon Sep 17 00:00:00 2001 From: xavier Date: Thu, 17 Jan 2019 16:22:24 +0100 Subject: [PATCH 37/42] Fix document list grid on team storage --- src/DAMBundle/Resources/config/oro/datagrids.yml | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/DAMBundle/Resources/config/oro/datagrids.yml b/src/DAMBundle/Resources/config/oro/datagrids.yml index 6603481..b8e8598 100644 --- a/src/DAMBundle/Resources/config/oro/datagrids.yml +++ b/src/DAMBundle/Resources/config/oro/datagrids.yml @@ -157,12 +157,12 @@ datagrids: type: url route: kiboko_dam_document_view params: - - uuid + node: uuid update_link: type: url route: kiboko_dam_document_update params: - - uuid + node: uuid delete_link: type: url route: kiboko_api_delete_document From 4f5cee66ef118de936a23e1f8e923f779bf0763b Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Gr=C3=A9gory=20Planchat?= Date: Thu, 17 Jan 2019 16:22:58 +0100 Subject: [PATCH 38/42] Fixed tree URL generation --- src/DAMBundle/Controller/DocumentNodeController.php | 11 +++++------ src/DAMBundle/Entity/DocumentNode.php | 4 ++-- .../JsTree/DocumentNodeUpdateTreeHandler.php | 7 ++----- .../Resources/views/DocumentNode/browse.html.twig | 2 +- 4 files changed, 10 insertions(+), 14 deletions(-) diff --git a/src/DAMBundle/Controller/DocumentNodeController.php b/src/DAMBundle/Controller/DocumentNodeController.php index 7214b4a..a67893b 100644 --- a/src/DAMBundle/Controller/DocumentNodeController.php +++ b/src/DAMBundle/Controller/DocumentNodeController.php @@ -140,17 +140,16 @@ public function browseAction(TeamStorageNode $root, ?DocumentNode $node = null) * } * ) * @Route("/{root}/create", - * name="kiboko_dam_node_create", + * name="kiboko_dam_root_create", * requirements={ * "root"="[\da-f]{8}-[\da-f]{4}-[\da-f]{4}-[\da-f]{4}-[\da-f]{12}", - * "parent"="[\da-f]{8}-[\da-f]{4}-[\da-f]{4}-[\da-f]{4}-[\da-f]{12}" * }, * options={ * "expose"=true, * } * ) * @ParamConverter("root", - * class="KibokoDAMBundle:DocumentNode", + * class="KibokoDAMBundle:TeamStorageNode", * options={ * "mapping": { * "root": "uuid" @@ -178,10 +177,10 @@ public function browseAction(TeamStorageNode $root, ?DocumentNode $node = null) public function createAction( Request $request, DocumentNodeInterface $root, - DocumentNodeInterface $parent + ?DocumentNodeInterface $parent = null ) { $node = new DocumentNode(); - $node->setParent($parent); + $node->setParent($parent ?? $root); return $this->update($request, $node,$root); } @@ -210,7 +209,7 @@ public function createAction( * } * ) * @ParamConverter("root", - * class="KibokoDAMBundle:DocumentNode", + * class="KibokoDAMBundle:TeamStorageNode", * options={ * "mapping": { * "root": "uuid", diff --git a/src/DAMBundle/Entity/DocumentNode.php b/src/DAMBundle/Entity/DocumentNode.php index 3ee8e1c..7310acd 100644 --- a/src/DAMBundle/Entity/DocumentNode.php +++ b/src/DAMBundle/Entity/DocumentNode.php @@ -307,9 +307,9 @@ public function setUuid(UuidInterface $uuid): void } /** - * @return DocumentNodeInterface + * @return DocumentNodeInterface|null */ - public function getRoot(): DocumentNodeInterface + public function getRoot(): ?DocumentNodeInterface { return $this->root; } diff --git a/src/DAMBundle/JsTree/DocumentNodeUpdateTreeHandler.php b/src/DAMBundle/JsTree/DocumentNodeUpdateTreeHandler.php index 9dfd62b..12570c3 100644 --- a/src/DAMBundle/JsTree/DocumentNodeUpdateTreeHandler.php +++ b/src/DAMBundle/JsTree/DocumentNodeUpdateTreeHandler.php @@ -97,19 +97,16 @@ private function formatTree(array $entities, DocumentNodeInterface $root, Docume $formattedTree = []; $uuidOpenedNode = null; foreach ($entities as $entity) { - if( $entity === $node){ + if ($entity === $node) { $node = $this->formatEntity($root, $entity, true); - } - else { + } else { $node = $this->formatEntity($root, $entity); } $formattedTree[] = $node; } - $topNode = $this->formatEntity($root,$root); $topNode['parent'] = self::ROOT_PARENT_VALUE; - $formattedTree[] = $topNode; return $formattedTree; } diff --git a/src/DAMBundle/Resources/views/DocumentNode/browse.html.twig b/src/DAMBundle/Resources/views/DocumentNode/browse.html.twig index 88a61c3..965f93a 100644 --- a/src/DAMBundle/Resources/views/DocumentNode/browse.html.twig +++ b/src/DAMBundle/Resources/views/DocumentNode/browse.html.twig @@ -31,7 +31,7 @@
{{ UI.button({ - 'path' : path(routePrefix ~ 'create' , { parent: teamstorage.uuid, root: teamstorage.uuid}), + 'path' : path('kiboko_dam_root_create', { root: teamstorage.uuid}), 'iCss': 'fa-folder', 'label': 'kiboko.dam.documentnode.create_label'|trans({ '%entityName%': 'kiboko.dam.documentnode.entity_label'|trans }), 'title': 'kiboko.dam.documentnode.create_label'|trans({ '%entityName%': 'kiboko.dam.documentnode.entity_label'|trans }) From f3165ae0b6793d9ebec06922091701743f9c0b98 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Gr=C3=A9gory=20Planchat?= Date: Thu, 17 Jan 2019 16:31:21 +0100 Subject: [PATCH 39/42] Fixed DocumentNode form --- src/DAMBundle/Controller/DocumentNodeController.php | 2 +- .../Resources/translations/messages.fr_FR.yml | 1 - .../Resources/views/DocumentNode/update.html.twig | 10 +++++++++- 3 files changed, 10 insertions(+), 3 deletions(-) diff --git a/src/DAMBundle/Controller/DocumentNodeController.php b/src/DAMBundle/Controller/DocumentNodeController.php index a67893b..440d0a3 100644 --- a/src/DAMBundle/Controller/DocumentNodeController.php +++ b/src/DAMBundle/Controller/DocumentNodeController.php @@ -179,7 +179,7 @@ public function createAction( DocumentNodeInterface $root, ?DocumentNodeInterface $parent = null ) { - $node = new DocumentNode(); + $node = new DocumentNode($root); $node->setParent($parent ?? $root); return $this->update($request, $node,$root); diff --git a/src/DAMBundle/Resources/translations/messages.fr_FR.yml b/src/DAMBundle/Resources/translations/messages.fr_FR.yml index 38d6c79..ebaccc9 100644 --- a/src/DAMBundle/Resources/translations/messages.fr_FR.yml +++ b/src/DAMBundle/Resources/translations/messages.fr_FR.yml @@ -10,7 +10,6 @@ kiboko: documentnode: entity_label: "Dossier" - create_label: "Créer un %entityName%" entity_plural_label: "Dossiers" reset: "Reset" empty_node: "Ce dossier est vide, de nouvequx fichiers apparaitront une fois que vous aurez envoyé de nouveaux fichiers par lots." diff --git a/src/DAMBundle/Resources/views/DocumentNode/update.html.twig b/src/DAMBundle/Resources/views/DocumentNode/update.html.twig index b8557b1..d7377f7 100644 --- a/src/DAMBundle/Resources/views/DocumentNode/update.html.twig +++ b/src/DAMBundle/Resources/views/DocumentNode/update.html.twig @@ -7,12 +7,20 @@ {% if node.id %} {% set formAction = path('kiboko_dam_node_update', { 'node': node.uuid }) %} {% else %} + {% if node.root %} {% set formAction = path('kiboko_dam_node_create', { 'parent': node.uuid, 'root': node.root.uuid }) %} + {% else %} + {% set formAction = path('kiboko_dam_node_create', { 'root': node.root.uuid }) %} + {% endif %} {% endif %} {% block navButtons %} - {{ UI.cancelButton(path('kiboko_dam_node_browse', { root: node.root.uuid, node: node.uuid})) }} + {% if node.root %} + {{ UI.cancelButton(path('kiboko_dam_node_browse', { root: node.root.uuid, node: node.uuid})) }} + {% else %} + {{ UI.cancelButton(path('kiboko_dam_node_browse', { root: node.uuid})) }} + {% endif %} {% set html = UI.saveAndCloseButton({ 'route': 'kiboko_dam_root_browse', From 29057c994e0a35cb9aa6e0a235fd7c9f6c0f540b Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Gr=C3=A9gory=20Planchat?= Date: Thu, 17 Jan 2019 16:35:27 +0100 Subject: [PATCH 40/42] Fixed JsTree root node ID --- src/DAMBundle/JsTree/DocumentNodeUpdateTreeHandler.php | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/src/DAMBundle/JsTree/DocumentNodeUpdateTreeHandler.php b/src/DAMBundle/JsTree/DocumentNodeUpdateTreeHandler.php index 12570c3..596fe47 100644 --- a/src/DAMBundle/JsTree/DocumentNodeUpdateTreeHandler.php +++ b/src/DAMBundle/JsTree/DocumentNodeUpdateTreeHandler.php @@ -103,11 +103,13 @@ private function formatTree(array $entities, DocumentNodeInterface $root, Docume $node = $this->formatEntity($root, $entity); } + if ($entity->getParent() === $root) { + $node['parent'] = self::ROOT_PARENT_VALUE; + } + $formattedTree[] = $node; } - $topNode['parent'] = self::ROOT_PARENT_VALUE; - return $formattedTree; } From 349cb202a37fc64e86f61e3645f2e446b9bc9df2 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Gr=C3=A9gory=20Planchat?= Date: Thu, 17 Jan 2019 16:47:21 +0100 Subject: [PATCH 41/42] Removed Document datagrid listener --- .../DocumentDatagridListener.php | 34 ------------------- src/DAMBundle/Resources/config/services.yml | 9 ----- 2 files changed, 43 deletions(-) delete mode 100644 src/DAMBundle/EventListener/DocumentDatagridListener.php diff --git a/src/DAMBundle/EventListener/DocumentDatagridListener.php b/src/DAMBundle/EventListener/DocumentDatagridListener.php deleted file mode 100644 index 4729f58..0000000 --- a/src/DAMBundle/EventListener/DocumentDatagridListener.php +++ /dev/null @@ -1,34 +0,0 @@ -em = $em; - } - - /** - * @param BuildBefore $event - */ - public function onBuildBefore(BuildBefore $event) - { - if ($event->getDatagrid()->getParameters()->get('_parameters')) { - $uuid = $event->getDatagrid()->getParameters()->get('_parameters'); - $uuid = $uuid['parent']; - - $node = $this->em->getRepository(DocumentNode::class)->findOneBy(['uuid' => $uuid]); - $event->getDatagrid()->getParameters()->set('parent', $node->getUuid()); - } - } -} diff --git a/src/DAMBundle/Resources/config/services.yml b/src/DAMBundle/Resources/config/services.yml index c5a8842..bd7c14b 100644 --- a/src/DAMBundle/Resources/config/services.yml +++ b/src/DAMBundle/Resources/config/services.yml @@ -1,5 +1,3 @@ -parameters: - kiboko_dam.event_listener.document_filesize_formatter: Kiboko\Bundle\DAMBundle\EventListener\DocumentDatagridListener services: kiboko_dam.form.type.document: class: Kiboko\Bundle\DAMBundle\Form\Type\DocumentType @@ -69,13 +67,6 @@ services: tags: - { name: kernel.event_listener, event: oro_menu.configure.application_menu, method: onNavigationConfigure } - kiboko_dam.event_listener.document_datagrid: - class: Kiboko\Bundle\DAMBundle\EventListener\DocumentDatagridListener - arguments: - - '@doctrine.orm.entity_manager' - tags: - - { name: kernel.event_listener, event: oro_datagrid.datagrid.build.before.kiboko-dam-documents-grid, method: onBuildBefore } - kiboko_dam.document_manager.api: class: Oro\Bundle\SoapBundle\Entity\Manager\ApiEntityManager parent: oro_soap.manager.entity_manager.abstract From 19f48723b3233e6b9b49dcf6c61fd8857b53db9d Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Gr=C3=A9gory=20Planchat?= Date: Thu, 17 Jan 2019 17:19:05 +0100 Subject: [PATCH 42/42] Fixed JsTree interactions with the datagrid --- .../JsTree/DocumentNodeUpdateTreeHandler.php | 14 +++- .../public/js/app/views/tree-manage-view.js | 84 ++++++++++--------- 2 files changed, 56 insertions(+), 42 deletions(-) diff --git a/src/DAMBundle/JsTree/DocumentNodeUpdateTreeHandler.php b/src/DAMBundle/JsTree/DocumentNodeUpdateTreeHandler.php index 596fe47..d4b6688 100644 --- a/src/DAMBundle/JsTree/DocumentNodeUpdateTreeHandler.php +++ b/src/DAMBundle/JsTree/DocumentNodeUpdateTreeHandler.php @@ -98,7 +98,7 @@ private function formatTree(array $entities, DocumentNodeInterface $root, Docume $uuidOpenedNode = null; foreach ($entities as $entity) { if ($entity === $node) { - $node = $this->formatEntity($root, $entity, true); + $node = $this->formatEntity($root, $entity, true, true); } else { $node = $this->formatEntity($root, $entity); } @@ -131,21 +131,27 @@ private function buildCode(DocumentNodeInterface $entity): string * @param TeamStorageNode $root * @param DocumentNodeInterface $entity * @param bool $isOpened + * @param bool $isSelected * * @return array */ - private function formatEntity(TeamStorageNode $root, DocumentNodeInterface $entity, bool $isOpened = false) - { + private function formatEntity( + TeamStorageNode $root, + DocumentNodeInterface $entity, + bool $isOpened = false, + bool $isSelected = false + ) { return [ 'id' => $this->buildCode($entity), 'uuid' => $entity->getUuid()->toString(), 'storage' => $root->getUuid()->toString(), + 'parentUuid' => $entity->getParent()->getUuid(), 'parent' => $entity->getParent() ? $this->buildCode($entity->getParent()) : self::ROOT_PARENT_VALUE, 'text' => $this->getLabel($entity), 'state' => [ 'opened' => $isOpened, 'disabled' => false, - 'selected' => $isOpened, + 'selected' => $isSelected, ], //'li_attr' => !$entity->isDisplayed() ? ['class' => 'hidden'] : [] ]; diff --git a/src/DAMBundle/Resources/public/js/app/views/tree-manage-view.js b/src/DAMBundle/Resources/public/js/app/views/tree-manage-view.js index 12479b5..0ac828f 100644 --- a/src/DAMBundle/Resources/public/js/app/views/tree-manage-view.js +++ b/src/DAMBundle/Resources/public/js/app/views/tree-manage-view.js @@ -68,12 +68,11 @@ define(function (require) { * Refresh buttons route with uuid provided * @param nodeUuid */ - refreshButtonsRoute: function (nodeUuid) { + refreshButtonsRoute: function (nodeUuid, rootUuid) { this.createNodeWidget.attr('href', routing.generate('kiboko_dam_node_create', { 'parent': nodeUuid, - 'root': this.rootUuid + 'root': rootUuid, })); - }, /** @@ -134,17 +133,16 @@ define(function (require) { * @param {Object} data */ onNodeOpen: function (e, data) { + var url = routing.generate('kiboko_dam_node_browse', { + 'parent': data.node.parentUuid, + 'root': data.node.storage + }); + window.history.pushState("", "", url); - var url = window.location.pathname; - var regex = /browse(.*)/g; - var newUrl = 'browse/'; - newUrl += this.formatUuuid(data.node.id); - window.history.pushState("", "", url.replace(regex,newUrl)); - - - this.reloadDocumentGrid(this.formatUuuid(data.node.id)); - this.refreshButtonsRoute(this.formatUuuid(data.node.id)); + this.reloadDocumentGrid(data.node.uuid); + this.refreshButtonsRoute(data.node.uuid); }, + /** * Triggers after node deleted in tree * @@ -158,8 +156,9 @@ define(function (require) { this.tree.jstree("refresh"); return; } - var uuid = this.formatUuuid(data.node.id); - var uuidParent = this.formatUuuid(data.parent); + + var uuid = data.node.uuid; + var uuidParent = data.node.parentUuid; if (uuid && uuidParent) { @@ -168,6 +167,7 @@ define(function (require) { node: uuid, parent: uuidParent }); + $.ajax({ async: true, type: 'POST', @@ -186,20 +186,24 @@ define(function (require) { */ onNodeNameChange: function (e, data) { var uuid = data.node.original.uuid; - if (uuid) { - var name = data.text; - if (data.node.original.uuid !== '') { - var url = routing.generate('kiboko_dam_document_node_tree_ajax_rename', {node: uuid}); - $.ajax({ - async: true, - type: 'POST', - data: { - 'newName': name - }, - url: url - }); - } + if (!uuid) { + return; + } + + var name = data.text; + if (data.node.original.uuid === '') { + return; } + + var url = routing.generate('kiboko_dam_document_node_tree_ajax_rename', {node: uuid}); + $.ajax({ + async: true, + type: 'POST', + data: { + 'newName': name + }, + url: url + }); }, /** @@ -212,16 +216,18 @@ define(function (require) { var parent = data.parent; var name = data.node.original.text; - if (data.node.original.uuid !== '') { - var url = routing.generate('kiboko_dam_document_node_tree_ajax_create', {node: this.formatUuuid(parent)}); - $.ajax({ - type: 'POST', - data: { - 'name': name, - }, - url: url - }); + if (data.node.original.uuid === '') { + return; } + + var url = routing.generate('kiboko_dam_document_node_tree_ajax_create', {node: this.formatUuuid(parent)}); + $.ajax({ + type: 'POST', + data: { + 'name': name, + }, + url: url + }); }, /** @@ -268,10 +274,12 @@ define(function (require) { } } return true; // allow everything else - } + }; + config.root = { "valid_children": ["default"], - } + }; + if (this.checkboxEnabled) { // config.plugins.push('checkbox'); config.plugins.push('contextmenu');