/** * Takes each view widgetmap array and convert it to persisted WidgetMaps. * * sort widget in inversed order to generate a reversed tree like: * 4 * 3 ┴ * 2 ┴ * 1 ┴ * * Then add the overwrited widgetmaps as: * 4 * 3 ┴ 7 * 2 ┴ 5 * 1 ┴ ┴ 6 * ┴ 8 * * @param InputInterface $input * @param OutputInterface $output * * @return void */ protected function execute(InputInterface $input, OutputInterface $output) { $em = $this->getContainer()->get('doctrine.orm.entity_manager'); $widgetRepo = $em->getRepository('VictoireWidgetBundle:Widget'); $widgetMapRepo = $em->getRepository('VictoireWidgetMapBundle:WidgetMap'); if ($viewId = $input->getOption('view')) { $views = [$em->getRepository('VictoireCoreBundle:View')->find($viewId)]; } else { $templateRepo = $em->getRepository('VictoireTemplateBundle:Template'); $rootTemplates = $templateRepo->getInstance()->where('template.template IS NULL')->getQuery()->getResult(); $templates = []; $recursiveGetTemplates = function ($template) use(&$recursiveGetTemplates, &$templates) { array_push($templates, $template); foreach ($template->getInheritors() as $template) { if ($template instanceof Template) { $recursiveGetTemplates($template); } } }; foreach ($rootTemplates as $rootTemplate) { $recursiveGetTemplates($rootTemplate); } $pageRepo = $em->getRepository('VictoirePageBundle:BasePage'); $pages = $pageRepo->findAll(); $errorRepo = $em->getRepository('VictoireTwigBundle:ErrorPage'); $errorPages = $errorRepo->findAll(); $views = array_merge($templates, array_merge($pages, $errorPages)); } /** @var View $view */ foreach ($views as $view) { $this->getContainer()->get('victoire_widget_map.builder')->build($view); $widgets = []; foreach ($view->getWidgets() as $widget) { $widgets[$widget->getId()] = $widget; } $oldWidgetMaps = $view->getWidgetMap(); if (!empty($oldWidgetMaps)) { foreach ($oldWidgetMaps as $slot => $oldWidgetMap) { $widgetMaps = []; usort($oldWidgetMap, function ($a, $b) { if ($b['position'] - $a['position'] == 0) { return 1; } return $b['position'] - $a['position']; }); foreach ($oldWidgetMap as $key => $item) { if ($item['action'] !== 'create') { unset($oldWidgetMap[$key]); $oldWidgetMap[] = $item; } } foreach ($oldWidgetMap as $key => $item) { if ($item['positionReference'] != null) { foreach ($oldWidgetMap as $_key => $_item) { if ($_item['widgetId'] == $item['positionReference']) { array_splice($oldWidgetMap[$_key], 0, 0, [$item]); unset($oldWidgetMap[$key]); } } } } foreach ($oldWidgetMap as $position => $_oldWidgetMap) { $output->writeln('=========================='); $output->writeln($slot); $widget = $widgetRepo->find($_oldWidgetMap['widgetId']); if (!$widget) { $output->writeln('widget does not exists'); continue; } $widgetMap = new WidgetMap(); $referencedWidgetMap = null; if ($_oldWidgetMap['positionReference'] != 0 && $_oldWidgetMap['positionReference'] != null) { $output->writeln('has positionReference'); $referencedWidget = $widgetRepo->find($_oldWidgetMap['positionReference']); $output->writeln($referencedWidget->getId()); $referencedWidgetMap = WidgetMapHelper::getWidgetMapByWidgetAndView($referencedWidget, $view); while ($referencedWidgetMap->getChild(WidgetMap::POSITION_AFTER)) { $referencedWidgetMap = $referencedWidgetMap->getChild(WidgetMap::POSITION_AFTER); } $output->writeln('set parent' . $referencedWidgetMap->getWidget()->getId()); $widgetMap->setParent($referencedWidgetMap); $widgetMap->setPosition(WidgetMap::POSITION_AFTER); } else { $output->writeln('has no positionReference'); if ($position == 0) { if (!isset($view->getBuiltWidgetMap()[$slot])) { $widgetMap->setPosition(null); $output->writeln('set parent' . null); $widgetMap->setParent(null); } else { $widgetMap->setPosition(WidgetMap::POSITION_AFTER); $_rootBuilt = null; foreach ($view->getBuiltWidgetMap()[$slot] as $_built) { if (!$_built->getParent()) { $_rootBuilt = $_built; break; } } while (null !== ($child = $_rootBuilt->getChildren($view)[WidgetMap::POSITION_BEFORE])) { $_rootBuilt = $_rootBuilt->getChildren($view)[WidgetMap::POSITION_BEFORE]; } $widgetMap->setParent($_rootBuilt); } } else { $widgetMap->setPosition(WidgetMap::POSITION_BEFORE); if (!empty(array_slice($widgetMaps, -1))) { $widgetMap->setParent(array_slice($widgetMaps, -1)[0]); } } } if (WidgetMap::ACTION_OVERWRITE == $_oldWidgetMap['action']) { $output->writeln('is overwrite'); /* @var Widget $replacedWidget */ if ($_oldWidgetMap['replacedWidgetId']) { $output->writeln('has replacedWidgetId'); $replacedWidget = $widgetRepo->find($_oldWidgetMap['replacedWidgetId']); $supplicantWidget = $widgetRepo->find($_oldWidgetMap['widgetId']); $replacedWidgetView = $replacedWidget->getView(); $this->getContainer()->get('victoire_widget_map.builder')->build($replacedWidgetView); try { $replacedWidgetMap = WidgetMapHelper::getWidgetMapByWidgetAndView($replacedWidget, $replacedWidgetView); $output->writeln('has replacedWidgetMap'); $widgetMap->setReplaced($replacedWidgetMap); $output->writeln('replace ' . $replacedWidget->getId() . ' by ' . $supplicantWidget->getId()); $widgetMap->setWidget($supplicantWidget); $widgetMap->setPosition($replacedWidgetMap->getPosition()); $output->writeln('set parent' . ($replacedWidgetMap->getParent() ? $replacedWidgetMap->getParent()->getWidget()->getId() : null)); $widgetMap->setParent($replacedWidgetMap->getParent()); } catch (WidgetMapNotFoundException $e) { // If replaced widgetMap does not exists, this is not an overwrite but a create } } elseif ($referencedWidgetMap) { $output->writeln('move'); $this->getContainer()->get('victoire_widget_map.manager')->move($view, ['position' => WidgetMap::POSITION_AFTER, 'slot' => $slot, 'parentWidgetMap' => $referencedWidgetMap, 'widgetMap' => $_oldWidgetMap['widgetId']]); } else { $_oldWidgetMap['action'] = WidgetMap::ACTION_CREATE; } } elseif (WidgetMap::ACTION_DELETE == $_oldWidgetMap['action']) { $output->writeln('is delete'); $replacedWidget = $widgetRepo->find($_oldWidgetMap['widgetId']); $widgetMap->setPosition(null); $output->writeln('set parent' . null); $widgetMap->setParent(null); try { $deletedWidgetMap = WidgetMapHelper::getWidgetMapByWidgetAndView($replacedWidget, $view); $replacedWidgetView = $replacedWidget->getView(); $this->getContainer()->get('victoire_widget_map.builder')->build($replacedWidgetView); $replacedWidgetMap = WidgetMapHelper::getWidgetMapByWidgetAndView($replacedWidget, $replacedWidgetView); $widgetMap->setReplaced($replacedWidgetMap); $this->getContainer()->get('victoire_widget_map.manager')->moveChildren($view, $deletedWidgetMap->getChild(WidgetMap::POSITION_BEFORE), $deletedWidgetMap->getChild(WidgetMap::POSITION_AFTER), $deletedWidgetMap->getParent(), $deletedWidgetMap->getPosition()); } catch (WidgetMapNotFoundException $e) { continue; } } $widgetMap->setAction($_oldWidgetMap['action']); $widgetMap->setWidget($widget); $widgetMap->setAsynchronous($_oldWidgetMap['asynchronous'] ? true : false); $widgetMap->setSlot($slot); $output->writeln('add widgetMap for widget ' . $widgetMap->getWidget()->getId() . ' to view ' . $view->getId()); $view->addWidgetMap($widgetMap); $em->persist($widgetMap); $widgetMaps[] = $widgetMap; $this->getContainer()->get('victoire_widget_map.builder')->build($view); } } } $em->flush(); } }
/** * Stylize a widget. * * @param Widget $widget The widget to stylize * @param int $viewReference The current view * * @return JsonResponse * * @Route("/victoire-dcms/widget/stylize/{id}/{viewReference}", name="victoire_core_widget_stylize", options={"expose"=true}) * @Template() */ public function stylizeAction(Request $request, Widget $widget, $viewReference) { $view = $this->getViewByReferenceId($viewReference); $this->get('victoire_widget_map.builder')->build($view, $this->get('doctrine.orm.entity_manager')); try { $widgetView = WidgetMapHelper::getWidgetMapByWidgetAndView($widget, $view)->getView(); } catch (WidgetMapNotFoundException $e) { return new JsonResponse(['success' => false, 'message' => $e->getMessage()]); } if (!$view instanceof \Victoire\Bundle\TemplateBundle\Entity\Template) { $widgetViewReference = $this->get('victoire_view_reference.repository')->getOneReferenceByParameters(['viewId' => $view->getId()]); $widgetView->setReference($widgetViewReference); } $this->get('victoire_core.current_view')->setCurrentView($view); try { if ($request->getMethod() === 'POST') { $form = $this->get('form.factory')->create(WidgetStyleType::class, $widget, ['method' => 'POST', 'action' => $this->generateUrl('victoire_core_widget_stylize', ['id' => $widget->getId(), 'viewReference' => $viewReference])]); $form->handleRequest($this->get('request')); if ($request->query->get('novalidate', false) === false && $form->isValid()) { if ($form->has('deleteBackground') && $form->get('deleteBackground')->getData()) { // @todo: dynamic responsive key foreach (['', 'XS', 'SM', 'MD', 'LG'] as $key) { $widget->{'deleteBackground' . $key}(); } } $this->get('doctrine.orm.entity_manager')->flush(); $params = ['view' => $view, 'success' => true, 'html' => $this->get('victoire_widget.widget_renderer')->render($widget, $view), 'widgetId' => $widget->getId(), 'viewCssHash' => $view->getCssHash()]; } else { $template = $request->query->get('novalidate', false) !== false ? 'VictoireCoreBundle:Widget/Form/stylize:form.html.twig' : 'VictoireCoreBundle:Widget/Form:stylize.html.twig'; $params = ['success' => !$form->isSubmitted(), 'html' => $this->get('templating')->render($template, ['view' => $view, 'form' => $form->createView(), 'widget' => $widget])]; } } else { $widgets = $widget->getWidgetMap()->getWidgets(); $forms = []; foreach ($widgets as $widget) { $forms[] = $this->get('form.factory')->create(WidgetStyleType::class, $widget, ['method' => 'POST', 'action' => $this->generateUrl('victoire_core_widget_stylize', ['id' => $widget->getId(), 'viewReference' => $viewReference])])->createView(); } $params = ['html' => $this->get('templating')->render('VictoireCoreBundle:Widget/Form:stylize.html.twig', ['view' => $view, 'forms' => $forms, 'widget' => $widget, 'widgets' => $widgets])]; } $response = new JsonResponse($params); } catch (Exception $ex) { $response = $this->getJsonReponseFromException($ex); } return $response; }
/** * render a widget. * * @param Widget $widget * @param View $view * * @return string */ public function renderContainer(Widget $widget, View $view) { $dispatcher = $this->container->get('event_dispatcher'); $dispatcher->dispatch(VictoireCmsEvents::WIDGET_PRE_RENDER, new WidgetRenderEvent($widget)); $widgetMap = WidgetMapHelper::getWidgetMapByWidgetAndView($widget, $view); $directive = ''; if ($this->container->get('security.authorization_checker')->isGranted('ROLE_VICTOIRE')) { $directive = 'widget'; } $id = 'vic-widget-' . $widget->getId() . '-container'; $html = sprintf('<div %s widget-map="%s" id="%s" class="vic-widget-container" data-id="%s">', $directive, $widgetMap->getId(), $id, $widget->getId()); if ($this->widgetHelper->isCacheEnabled($widget)) { $content = $this->widgetCache->fetch($widget); if (null === $content) { $content = $this->render($widget, $view); $this->widgetCache->save($widget, $content); } else { $this->victoireCollector->addCachedWidget($widget); } } else { $content = $this->render($widget, $view); } $html .= $content; $html .= '</div>'; //close container $dispatcher->dispatch(VictoireCmsEvents::WIDGET_POST_RENDER, new WidgetRenderEvent($widget, $html)); return $html; }
/** * Delete the widget from the view. * * @param View $view * @param Widget $widget * * @throws \Exception Widget map does not exists */ public function delete(View $view, Widget $widget) { $this->builder->build($view); $widgetMap = WidgetMapHelper::getWidgetMapByWidgetAndView($widget, $view); $slot = $widgetMap->getSlot(); $originalParent = $widgetMap->getParent(); $originalPosition = $widgetMap->getPosition(); $children = $widgetMap->getChildren($view); $beforeChild = !empty($children[WidgetMap::POSITION_BEFORE]) ? $children[WidgetMap::POSITION_BEFORE] : null; $afterChild = !empty($children[WidgetMap::POSITION_AFTER]) ? $children[WidgetMap::POSITION_AFTER] : null; //we remove the widget from the current view if ($widgetMap->getView() === $view) { // If the widgetMap has substitutes, delete them or transform them in create mode if (count($widgetMap->getSubstitutes()) > 0) { foreach ($widgetMap->getSubstitutes() as $substitute) { if ($substitute->getAction() === WidgetMap::ACTION_OVERWRITE) { $substitute->setAction(WidgetMap::ACTION_CREATE); $substitute->setReplaced(null); } else { $view->removeWidgetMap($widgetMap); } } } //remove the widget map from the slot $view->removeWidgetMap($widgetMap); } else { //the widget is owned by another view (a parent) //so we add a new widget map that indicates we delete this widget $replaceWidgetMap = new WidgetMap(); $replaceWidgetMap->setAction(WidgetMap::ACTION_DELETE); $replaceWidgetMap->setWidget($widget); $replaceWidgetMap->setSlot($slot); $replaceWidgetMap->setReplaced($widgetMap); $view->addWidgetMap($replaceWidgetMap); } $this->moveChildren($view, $beforeChild, $afterChild, $originalParent, $originalPosition); }
/** * Remove a widget. * * @param Widget $widget * * @return array The parameter for the view */ public function deleteWidget(Widget $widget, View $view) { //Used to update view in callback (we do it before delete it else it'll not exists anymore) $widgetId = $widget->getId(); //we update the widget map of the view $this->widgetMapBuilder->build($view); $widgetMap = WidgetMapHelper::getWidgetMapByWidgetAndView($widget, $view); //the widget is removed only if the current view is the view of the widget if ($widgetMap->getView() == $view && $widgetMap->getAction() != WidgetMap::ACTION_DELETE) { //we remove the widget $this->entityManager->remove($widget); } //we update the view $this->entityManager->persist($view); //update the view deleting the widget $this->widgetMapManager->delete($view, $widget); $this->entityManager->flush(); return ['success' => true, 'widgetId' => $widgetId, 'viewCssHash' => $view->getCssHash()]; }