diff --git a/.gitignore b/.gitignore index 2823a707..be338d9b 100644 --- a/.gitignore +++ b/.gitignore @@ -4,9 +4,9 @@ /vendor # PHPUnit +/build /phpunit.xml /clover.xml -/report # Coveralls /coveralls.json diff --git a/DependencyInjection/Compiler/AssetsHelperCompilerPass.php b/DependencyInjection/Compiler/AssetsHelperCompilerPass.php index 66bf5c45..e54c15bb 100644 --- a/DependencyInjection/Compiler/AssetsHelperCompilerPass.php +++ b/DependencyInjection/Compiler/AssetsHelperCompilerPass.php @@ -19,6 +19,7 @@ * Create assets.packages fallback alias for Symfony < 2.7 * * @author Adam Misiorny + * @author GeLo */ class AssetsHelperCompilerPass implements CompilerPassInterface { @@ -27,8 +28,8 @@ class AssetsHelperCompilerPass implements CompilerPassInterface */ public function process(ContainerBuilder $container) { - if (Kernel::VERSION_ID < 20700 && $container->has('templating.helper.assets')) { - $container->setAlias('assets.packages', 'templating.helper.assets'); + if (Kernel::VERSION_ID < 20700 && $container->hasDefinition($definition = 'templating.helper.assets')) { + $container->setAlias('assets.packages', $definition); } } } diff --git a/DependencyInjection/Compiler/ResourceCompilerPass.php b/DependencyInjection/Compiler/ResourceCompilerPass.php index 2705cf09..f1658d77 100644 --- a/DependencyInjection/Compiler/ResourceCompilerPass.php +++ b/DependencyInjection/Compiler/ResourceCompilerPass.php @@ -26,24 +26,22 @@ class ResourceCompilerPass implements CompilerPassInterface */ public function process(ContainerBuilder $container) { - $templatingEngines = $container->getParameter('templating.engines'); - - if (in_array('php', $templatingEngines)) { + if ($container->hasParameter($parameter = 'templating.helper.form.resources')) { $container->setParameter( - 'templating.helper.form.resources', + $parameter, array_merge( array('IvoryCKEditorBundle:Form'), - $container->getParameter('templating.helper.form.resources') + $container->getParameter($parameter) ) ); } - if (in_array('twig', $templatingEngines)) { + if ($container->hasParameter($parameter = 'twig.form.resources')) { $container->setParameter( - 'twig.form.resources', + $parameter, array_merge( array('IvoryCKEditorBundle:Form:ckeditor_widget.html.twig'), - $container->getParameter('twig.form.resources') + $container->getParameter($parameter) ) ); } diff --git a/DependencyInjection/Compiler/TemplatingCompilerPass.php b/DependencyInjection/Compiler/TemplatingCompilerPass.php new file mode 100644 index 00000000..91611ae9 --- /dev/null +++ b/DependencyInjection/Compiler/TemplatingCompilerPass.php @@ -0,0 +1,37 @@ + + * + * For the full copyright and license information, please read the LICENSE + * file that was distributed with this source code. + */ + +namespace Ivory\CKEditorBundle\DependencyInjection\Compiler; + +use Symfony\Component\DependencyInjection\Compiler\CompilerPassInterface; +use Symfony\Component\DependencyInjection\ContainerBuilder; + +/** + * Templating compiler pass. + * + * @author GeLo + */ +class TemplatingCompilerPass implements CompilerPassInterface +{ + /** + * {@inheritdoc} + */ + public function process(ContainerBuilder $container) + { + if (!$container->hasDefinition('templating.engine.php')) { + $container->removeDefinition('ivory_ck_editor.templating.helper'); + } + + if (!$container->hasDefinition('twig')) { + $container->removeDefinition('ivory_ck_editor.twig_extension'); + } + } +} diff --git a/DependencyInjection/IvoryCKEditorExtension.php b/DependencyInjection/IvoryCKEditorExtension.php index 2d2ef111..8a8ef904 100644 --- a/DependencyInjection/IvoryCKEditorExtension.php +++ b/DependencyInjection/IvoryCKEditorExtension.php @@ -31,7 +31,7 @@ class IvoryCKEditorExtension extends ConfigurableExtension protected function loadInternal(array $config, ContainerBuilder $container) { $loader = new XmlFileLoader($container, new FileLocator(__DIR__.'/../Resources/config')); - foreach (array('form', 'templating', 'twig') as $service) { + foreach (array('form', 'renderer', 'templating', 'twig') as $service) { $loader->load($service.'.xml'); } diff --git a/IvoryCKEditorBundle.php b/IvoryCKEditorBundle.php index 0cb705ad..cf288f5e 100644 --- a/IvoryCKEditorBundle.php +++ b/IvoryCKEditorBundle.php @@ -13,6 +13,7 @@ use Ivory\CKEditorBundle\DependencyInjection\Compiler\AssetsHelperCompilerPass; use Ivory\CKEditorBundle\DependencyInjection\Compiler\ResourceCompilerPass; +use Ivory\CKEditorBundle\DependencyInjection\Compiler\TemplatingCompilerPass; use Symfony\Component\HttpKernel\Bundle\Bundle; use Symfony\Component\DependencyInjection\ContainerBuilder; @@ -30,7 +31,8 @@ class IvoryCKEditorBundle extends Bundle public function build(ContainerBuilder $container) { $container + ->addCompilerPass(new AssetsHelperCompilerPass()) ->addCompilerPass(new ResourceCompilerPass()) - ->addCompilerPass(new AssetsHelperCompilerPass()); + ->addCompilerPass(new TemplatingCompilerPass()); } } diff --git a/Renderer/CKEditorRenderer.php b/Renderer/CKEditorRenderer.php new file mode 100644 index 00000000..38a7bd56 --- /dev/null +++ b/Renderer/CKEditorRenderer.php @@ -0,0 +1,318 @@ + + * + * For the full copyright and license information, please read the LICENSE + * file that was distributed with this source code. + */ + +namespace Ivory\CKEditorBundle\Renderer; + +use Ivory\JsonBuilder\JsonBuilder; +use Symfony\Component\DependencyInjection\ContainerInterface; + +/** + * @author GeLo + */ +class CKEditorRenderer implements CKEditorRendererInterface +{ + /** @var \Ivory\JsonBuilder\JsonBuilder */ + private $jsonBuilder; + + /** @var \Symfony\Component\DependencyInjection\ContainerInterface */ + private $container; + + /** + * Creates a CKEditor renderer. + * + * @param \Symfony\Component\DependencyInjection\ContainerInterface $container The container. + */ + public function __construct(ContainerInterface $container) + { + $this->jsonBuilder = new JsonBuilder(); + $this->container = $container; + } + + /** + * {@inheritdoc} + */ + public function renderBasePath($basePath) + { + return $this->fixPath($this->fixUrl($basePath)); + } + + /** + * {@inheritdoc} + */ + public function renderJsPath($jsPath) + { + return $this->fixUrl($jsPath); + } + + /** + * {@inheritdoc} + */ + public function renderWidget($id, array $config, array $options = array()) + { + $config = $this->fixConfigLanguage($config); + $config = $this->fixConfigContentsCss($config); + $config = $this->fixConfigFilebrowsers($config); + + $this->jsonBuilder + ->reset() + ->setValues($config); + + $this->fixConfigEscapedValues($config); + + $autoInline = isset($options['auto_inline']) && !$options['auto_inline'] + ? 'CKEDITOR.disableAutoInline = true;'.PHP_EOL + : null; + + $widget = sprintf( + 'CKEDITOR.%s("%s", %s);', + isset($options['inline']) && $options['inline'] ? 'inline' : 'replace', + $id, + $this->fixConfigConstants($this->jsonBuilder->build()) + ); + + if (isset($options['input_sync']) && $options['input_sync']) { + $variable = 'ivory_ckeditor_'.$id; + $widget = 'var '.$variable.' = '.$widget.PHP_EOL; + + return $autoInline.$widget.$variable.'.on(\'change\', function() { '.$variable.'.updateElement(); });'; + } + + return $autoInline.$widget; + } + + /** + * {@inheritdoc} + */ + public function renderDestroy($id) + { + return sprintf('if (CKEDITOR.instances["%s"]) { delete CKEDITOR.instances["%s"]; }', $id, $id); + } + + /** + * {@inheritdoc} + */ + public function renderPlugin($name, array $plugin) + { + return sprintf( + 'CKEDITOR.plugins.addExternal("%s", "%s", "%s");', + $name, + $this->fixPath($this->fixUrl($plugin['path'])), + $plugin['filename'] + ); + } + + /** + * {@inheritdoc} + */ + public function renderStylesSet($name, array $stylesSet) + { + $this->jsonBuilder + ->reset() + ->setValues($stylesSet); + + return sprintf( + 'if (CKEDITOR.stylesSet.get("%s") === null) { CKEDITOR.stylesSet.add("%s", %s); }', + $name, + $name, + $this->jsonBuilder->build() + ); + } + + /** + * {@inheritdoc} + */ + public function renderTemplate($name, array $template) + { + if (isset($template['imagesPath'])) { + $template['imagesPath'] = $this->fixPath($this->fixUrl($template['imagesPath'])); + } + + $this->jsonBuilder + ->reset() + ->setValues($template); + + return sprintf('CKEDITOR.addTemplates("%s", %s);', $name, $this->jsonBuilder->build()); + } + + /** + * Fixes the config language. + * + * @param array $config The config. + * + * @return array The fixed config. + */ + private function fixConfigLanguage(array $config) + { + if (isset($config['language'])) { + $config['language'] = strtolower(str_replace('_', '-', $config['language'])); + } + + return $config; + } + + /** + * Fixes the config contents css. + * + * @param array $config The config. + * + * @return array The fixed config. + */ + private function fixConfigContentsCss(array $config) + { + if (isset($config['contentsCss'])) { + $cssContents = (array) $config['contentsCss']; + + $config['contentsCss'] = array(); + foreach ($cssContents as $cssContent) { + $config['contentsCss'][] = $this->fixPath($this->fixUrl($cssContent)); + } + } + + return $config; + } + + /** + * Fixes the config filebrowsers. + * + * @param array $config The config. + * + * @return array The fixed config. + */ + private function fixConfigFilebrowsers(array $config) + { + $keys = array( + 'Browse', + 'FlashBrowse', + 'ImageBrowse', + 'ImageBrowseLink', + 'Upload', + 'FlashUpload', + 'ImageUpload', + ); + + foreach ($keys as $key) { + $fileBrowserKey = 'filebrowser'.$key; + $handler = $fileBrowserKey.'Handler'; + $url = $fileBrowserKey.'Url'; + $route = $fileBrowserKey.'Route'; + $routeParameters = $fileBrowserKey.'RouteParameters'; + $routeAbsolute = $fileBrowserKey.'RouteAbsolute'; + + if (isset($config[$handler])) { + $config[$url] = $config[$handler]($this->getRouter()); + } elseif (isset($config[$route])) { + $config[$url] = $this->getRouter()->generate( + $config[$route], + isset($config[$routeParameters]) ? $config[$routeParameters] : array(), + isset($config[$routeAbsolute]) ? $config[$routeAbsolute] : false + ); + } + + unset($config[$handler]); + unset($config[$route]); + unset($config[$routeParameters]); + unset($config[$routeAbsolute]); + } + + return $config; + } + + /** + * Fixes the config escaped values and sets them on the json builder. + * + * @param array $config The config. + */ + private function fixConfigEscapedValues(array $config) + { + if (isset($config['protectedSource'])) { + foreach ($config['protectedSource'] as $key => $value) { + $this->jsonBuilder->setValue(sprintf('[protectedSource][%s]', $key), $value, false); + } + } + + $escapedValueKeys = array( + 'stylesheetParser_skipSelectors', + 'stylesheetParser_validSelectors', + ); + + foreach ($escapedValueKeys as $escapedValueKey) { + if (isset($config[$escapedValueKey])) { + $this->jsonBuilder->setValue(sprintf('[%s]', $escapedValueKey), $config[$escapedValueKey], false); + } + } + } + + /** + * Fixes the config constants. + * + * @param string $json The json config. + * + * @return string The fixed config. + */ + private function fixConfigConstants($json) + { + return preg_replace('/"(CKEDITOR\.[A-Z_]+)"/', '$1', $json); + } + + /** + * Fixes a path. + * + * @param string $path The path. + * + * @return string The fixed path. + */ + private function fixPath($path) + { + if (($position = strpos($path, '?')) !== false) { + return substr($path, 0, $position); + } + + return $path; + } + + /** + * Fixes an url. + * + * @param string $url The url. + * + * @return string The fixed url. + */ + private function fixUrl($url) + { + $assetsHelper = $this->getAssetsHelper(); + + if ($assetsHelper !== null) { + $url = $assetsHelper->getUrl($url); + } + + return $url; + } + + /** + * Gets the assets helper. + * + * @return \Symfony\Component\Asset\Packages|\Symfony\Component\Templating\Helper\CoreAssetsHelper|null The assets helper. + */ + private function getAssetsHelper() + { + return $this->container->get('assets.packages', ContainerInterface::NULL_ON_INVALID_REFERENCE); + } + + /** + * Gets the router. + * + * @return \Symfony\Component\Routing\RouterInterface The router. + */ + private function getRouter() + { + return $this->container->get('router'); + } +} diff --git a/Renderer/CKEditorRendererInterface.php b/Renderer/CKEditorRendererInterface.php new file mode 100644 index 00000000..0bee0c22 --- /dev/null +++ b/Renderer/CKEditorRendererInterface.php @@ -0,0 +1,91 @@ + + * + * For the full copyright and license information, please read the LICENSE + * file that was distributed with this source code. + */ + +namespace Ivory\CKEditorBundle\Renderer; + +/** + * @author GeLo + */ +interface CKEditorRendererInterface +{ + /** + * Renders the base path. + * + * @param string $basePath The base path. + * + * @return string The rendered base path. + */ + public function renderBasePath($basePath); + + /** + * Renders the js path. + * + * @param string $jsPath The js path. + * + * @return string The rendered js path. + */ + public function renderJsPath($jsPath); + + /** + * Renders the widget. + * + * @param string $id The identifier. + * @param array $config The config. + * @param array $options The options. + * + * The available options are: + * - auto_inline: boolean + * - inline: boolean + * - input_sync: boolean + * + * @return string The rendered widget. + */ + public function renderWidget($id, array $config, array $options = array()); + + /** + * Renders the destroy. + * + * @param string $id The identifier. + * + * @return string The rendered destroy. + */ + public function renderDestroy($id); + + /** + * Renders a plugin. + * + * @param string $name The name. + * @param array $plugin The plugin. + * + * @return string The rendered plugin. + */ + public function renderPlugin($name, array $plugin); + + /** + * Renders a styles set. + * + * @param string $name The name + * @param array $stylesSet The style set. + * + * @return string The rendered style set. + */ + public function renderStylesSet($name, array $stylesSet); + + /** + * Renders a template. + * + * @param string $name The template name. + * @param array $template The template. + * + * @return string The rendered template. + */ + public function renderTemplate($name, array $template); +} diff --git a/Resources/config/renderer.xml b/Resources/config/renderer.xml new file mode 100644 index 00000000..bde589aa --- /dev/null +++ b/Resources/config/renderer.xml @@ -0,0 +1,12 @@ + + + + + + + + + diff --git a/Resources/config/templating.xml b/Resources/config/templating.xml index 855ab272..04034355 100644 --- a/Resources/config/templating.xml +++ b/Resources/config/templating.xml @@ -6,7 +6,7 @@ > - + diff --git a/Resources/config/twig.xml b/Resources/config/twig.xml index 6d2facc3..d445c67f 100644 --- a/Resources/config/twig.xml +++ b/Resources/config/twig.xml @@ -6,7 +6,7 @@ > - + diff --git a/Templating/CKEditorHelper.php b/Templating/CKEditorHelper.php index f6ca1927..34c1157a 100644 --- a/Templating/CKEditorHelper.php +++ b/Templating/CKEditorHelper.php @@ -11,7 +11,7 @@ namespace Ivory\CKEditorBundle\Templating; -use Ivory\JsonBuilder\JsonBuilder; +use Ivory\CKEditorBundle\Renderer\CKEditorRendererInterface; use Symfony\Component\DependencyInjection\ContainerInterface; use Symfony\Component\Templating\Helper\Helper; @@ -21,167 +21,93 @@ * @author GeLo * @author Adam Misiorny */ -class CKEditorHelper extends Helper +class CKEditorHelper extends Helper implements CKEditorRendererInterface { - /** @var \Ivory\JsonBuilder\JsonBuilder */ - private $jsonBuilder; - - /** @var \Symfony\Component\DependencyInjection\ContainerInterface */ - private $container; + /** @var \Ivory\CKEditorBundle\Renderer\CKEditorRendererInterface */ + private $renderer; /** * Creates a CKEditor template helper. * - * @param \Symfony\Component\DependencyInjection\ContainerInterface $container The container. + * @param \Ivory\CKEditorBundle\Renderer\CKEditorRendererInterface $renderer The CKEditor renderer. */ - public function __construct(ContainerInterface $container) + public function __construct($renderer) { - $this->jsonBuilder = new JsonBuilder(); - $this->container = $container; + if ($renderer instanceof ContainerInterface) { + @trigger_error(sprintf( + 'Passing a "%s" to the "%s" constructor has been deprecated in IvoryCKEditorBundle 4.0 and will be removed in 5.0. Use the "%s" instead.', + 'Symfony\Component\DependencyInjection\ContainerInterface', + 'Ivory\CKEditorBundle\Templating\CKEditorHelper', + 'Ivory\CKEditorBundle\Renderer\CKEditorRenderer' + ), E_USER_DEPRECATED); + + $renderer = $renderer->get('ivory_ck_editor.renderer'); + } + + if (!$renderer instanceof CKEditorRendererInterface) { + throw new \InvalidArgumentException(sprintf( + 'The CKEditor renderer must be an instance of "%s".', + 'Ivory\CKEditorBundle\Renderer\CKEditorRendererInterface' + )); + } + + $this->renderer = $renderer; } /** - * Renders the base path. - * - * @param string $basePath The base path. - * - * @return string The rendered base path. + * {@inheritdoc} */ public function renderBasePath($basePath) { - return $this->fixPath($this->fixUrl($basePath)); + return $this->renderer->renderBasePath($basePath); } /** - * Renders the js path. - * - * @param string $jsPath The js path. - * - * @return string The rendered js path. + * {@inheritdoc} */ public function renderJsPath($jsPath) { - return $this->fixUrl($jsPath); + return $this->renderer->renderJsPath($jsPath); } /** - * Renders the widget. - * - * @param string $id The identifier. - * @param array $config The config. - * @param array $options The options. - * - * The available options are: - * - auto_inline: boolean - * - inline: boolean - * - input_sync: boolean - * - * @return string The rendered widget. + * {@inheritdoc} */ public function renderWidget($id, array $config, array $options = array()) { - $config = $this->fixConfigLanguage($config); - $config = $this->fixConfigContentsCss($config); - $config = $this->fixConfigFilebrowsers($config); - - $this->jsonBuilder - ->reset() - ->setValues($config); - - $this->fixConfigEscapedValues($config); - - $autoInline = isset($options['auto_inline']) && !$options['auto_inline'] - ? 'CKEDITOR.disableAutoInline = true;'.PHP_EOL - : null; - - $widget = sprintf( - 'CKEDITOR.%s("%s", %s);', - isset($options['inline']) && $options['inline'] ? 'inline' : 'replace', - $id, - $this->fixConfigConstants($this->jsonBuilder->build()) - ); - - if (isset($options['input_sync']) && $options['input_sync']) { - $variable = 'ivory_ckeditor_'.$id; - $widget = 'var '.$variable.' = '.$widget.PHP_EOL; - - return $autoInline.$widget.$variable.'.on(\'change\', function() { '.$variable.'.updateElement(); });'; - } - - return $autoInline.$widget; + return $this->renderer->renderWidget($id, $config, $options); } /** - * Renders the destroy. - * - * @param string $id The identifier. - * - * @return string The rendered destroy. + * {@inheritdoc} */ public function renderDestroy($id) { - return sprintf('if (CKEDITOR.instances["%s"]) { delete CKEDITOR.instances["%s"]; }', $id, $id); + return $this->renderer->renderDestroy($id); } /** - * Renders a plugin. - * - * @param string $name The name. - * @param array $plugin The plugin. - * - * @return string The rendered plugin. + * {@inheritdoc} */ public function renderPlugin($name, array $plugin) { - return sprintf( - 'CKEDITOR.plugins.addExternal("%s", "%s", "%s");', - $name, - $this->fixPath($this->fixUrl($plugin['path'])), - $plugin['filename'] - ); + return $this->renderer->renderPlugin($name, $plugin); } /** - * Renders a styles set. - * - * @param string $name The name - * @param array $stylesSet The style set. - * - * @return string The rendered style set. + * {@inheritdoc} */ public function renderStylesSet($name, array $stylesSet) { - $this->jsonBuilder - ->reset() - ->setValues($stylesSet); - - return sprintf( - 'if (CKEDITOR.stylesSet.get("%s") === null) { CKEDITOR.stylesSet.add("%s", %s); }', - $name, - $name, - $this->jsonBuilder->build() - ); + return $this->renderer->renderStylesSet($name, $stylesSet); } /** - * Renders a template. - * - * @param string $name The template name. - * @param array $template The template. - * - * @return string The rendered template. + * {@inheritdoc} */ public function renderTemplate($name, array $template) { - if (isset($template['imagesPath'])) { - $template['imagesPath'] = $this->fixPath($this->fixUrl($template['imagesPath'])); - } - - $this->jsonBuilder - ->reset() - ->setValues($template); - - return sprintf('CKEDITOR.addTemplates("%s", %s);', $name, $this->jsonBuilder->build()); + return $this->renderer->renderTemplate($name, $template); } /** @@ -191,178 +117,4 @@ public function getName() { return 'ivory_ckeditor'; } - - /** - * Fixes the config language. - * - * @param array $config The config. - * - * @return array The fixed config. - */ - protected function fixConfigLanguage(array $config) - { - if (isset($config['language'])) { - $config['language'] = strtolower(str_replace('_', '-', $config['language'])); - } - - return $config; - } - - /** - * Fixes the config contents css. - * - * @param array $config The config. - * - * @return array The fixed config. - */ - private function fixConfigContentsCss(array $config) - { - if (isset($config['contentsCss'])) { - $cssContents = (array) $config['contentsCss']; - - $config['contentsCss'] = array(); - foreach ($cssContents as $cssContent) { - $config['contentsCss'][] = $this->fixPath($this->fixUrl($cssContent)); - } - } - - return $config; - } - - /** - * Fixes the config filebrowsers. - * - * @param array $config The config. - * - * @return array The fixed config. - */ - private function fixConfigFilebrowsers(array $config) - { - $keys = array( - 'Browse', - 'FlashBrowse', - 'ImageBrowse', - 'ImageBrowseLink', - 'Upload', - 'FlashUpload', - 'ImageUpload', - ); - - foreach ($keys as $key) { - $fileBrowserKey = 'filebrowser'.$key; - $handler = $fileBrowserKey.'Handler'; - $url = $fileBrowserKey.'Url'; - $route = $fileBrowserKey.'Route'; - $routeParameters = $fileBrowserKey.'RouteParameters'; - $routeAbsolute = $fileBrowserKey.'RouteAbsolute'; - - if (isset($config[$handler])) { - $config[$url] = $config[$handler]($this->getRouter()); - } elseif (isset($config[$route])) { - $config[$url] = $this->getRouter()->generate( - $config[$route], - isset($config[$routeParameters]) ? $config[$routeParameters] : array(), - isset($config[$routeAbsolute]) ? $config[$routeAbsolute] : false - ); - } - - unset($config[$handler]); - unset($config[$route]); - unset($config[$routeParameters]); - unset($config[$routeAbsolute]); - } - - return $config; - } - - /** - * Fixes the config escaped values and sets them on the json builder. - * - * @param array $config The config. - */ - private function fixConfigEscapedValues(array $config) - { - if (isset($config['protectedSource'])) { - foreach ($config['protectedSource'] as $key => $value) { - $this->jsonBuilder->setValue(sprintf('[protectedSource][%s]', $key), $value, false); - } - } - - $escapedValueKeys = array( - 'stylesheetParser_skipSelectors', - 'stylesheetParser_validSelectors', - ); - - foreach ($escapedValueKeys as $escapedValueKey) { - if (isset($config[$escapedValueKey])) { - $this->jsonBuilder->setValue(sprintf('[%s]', $escapedValueKey), $config[$escapedValueKey], false); - } - } - } - - /** - * Fixes the config constants. - * - * @param string $json The json config. - * - * @return string The fixed config. - */ - private function fixConfigConstants($json) - { - return preg_replace('/"(CKEDITOR\.[A-Z_]+)"/', '$1', $json); - } - - /** - * Fixes a path. - * - * @param string $path The path. - * - * @return string The fixed path. - */ - private function fixPath($path) - { - if (($position = strpos($path, '?')) !== false) { - return substr($path, 0, $position); - } - - return $path; - } - - /** - * Fixes an url. - * - * @param string $url The url. - * - * @return string The fixed url. - */ - private function fixUrl($url) - { - $assetsHelper = $this->getAssetsHelper(); - - if ($assetsHelper !== null) { - $url = $assetsHelper->getUrl($url); - } - - return $url; - } - - /** - * Gets the assets helper. - * - * @return \Symfony\Component\Asset\Packages|\Symfony\Component\Templating\Helper\CoreAssetsHelper|null The assets helper. - */ - private function getAssetsHelper() - { - return $this->container->get('assets.packages', ContainerInterface::NULL_ON_INVALID_REFERENCE); - } - - /** - * Gets the router. - * - * @return \Symfony\Component\Routing\RouterInterface The router. - */ - private function getRouter() - { - return $this->container->get('router'); - } } diff --git a/Tests/DependencyInjection/AbstractIvoryCKEditorExtensionTest.php b/Tests/DependencyInjection/AbstractIvoryCKEditorExtensionTest.php index d0f3a50e..d9aadd8b 100644 --- a/Tests/DependencyInjection/AbstractIvoryCKEditorExtensionTest.php +++ b/Tests/DependencyInjection/AbstractIvoryCKEditorExtensionTest.php @@ -11,7 +11,6 @@ namespace Ivory\CKEditorBundle\Tests\DependencyInjection; -use Ivory\CKEditorBundle\DependencyInjection\Compiler\ResourceCompilerPass; use Ivory\CKEditorBundle\DependencyInjection\IvoryCKEditorExtension; use Ivory\CKEditorBundle\Tests\Fixtures\Extension\FrameworkExtension; use Symfony\Component\DependencyInjection\ContainerBuilder; diff --git a/Tests/DependencyInjection/Compiler/AssetsHelperCompilerPassTest.php b/Tests/DependencyInjection/Compiler/AssetsHelperCompilerPassTest.php index 48d6e8b3..67af521b 100644 --- a/Tests/DependencyInjection/Compiler/AssetsHelperCompilerPassTest.php +++ b/Tests/DependencyInjection/Compiler/AssetsHelperCompilerPassTest.php @@ -18,6 +18,7 @@ * Assets helper compiler pass test. * * @author Adam Misiorny + * @author GeLo */ class AssetsHelperCompilerPassTest extends \PHPUnit_Framework_TestCase { @@ -46,14 +47,10 @@ public function testAssetsPackagesAliasWithTemplatingHelperAssets() $this->markTestSkipped(); } - $container = $this->getMockBuilder('Symfony\Component\DependencyInjection\ContainerBuilder') - ->setMethods(array('has', 'setAlias')) - ->disableOriginalConstructor() - ->getMock(); - + $container = $this->createContainerBuilderMock(); $container ->expects($this->once()) - ->method('has') + ->method('hasDefinition') ->with($this->identicalTo($legacy = 'templating.helper.assets')) ->will($this->returnValue(true)); @@ -74,14 +71,10 @@ public function testAssetsPackagesAliasWithoutTemplatingHelperAssets() $this->markTestSkipped(); } - $container = $this->getMockBuilder('Symfony\Component\DependencyInjection\ContainerBuilder') - ->setMethods(array('has', 'setAlias')) - ->disableOriginalConstructor() - ->getMock(); - + $container = $this->createContainerBuilderMock(); $container ->expects($this->once()) - ->method('has') + ->method('hasDefinition') ->with($this->identicalTo($legacy = 'templating.helper.assets')) ->will($this->returnValue(false)); @@ -98,15 +91,24 @@ public function testAssetsPackagesAliasWithAssetsPackage() $this->markTestSkipped(); } - $container = $this->getMockBuilder('Symfony\Component\DependencyInjection\ContainerBuilder') - ->setMethods(array('setAlias')) - ->disableOriginalConstructor() - ->getMock(); - + $container = $this->createContainerBuilderMock(); $container ->expects($this->never()) ->method('setAlias'); $this->assetsHelperCompilerPass->process($container); } + + /** + * Creates a container builder mock. + * + * @return \Symfony\Component\DependencyInjection\ContainerBuilder|\PHPUnit_Framework_MockObject_MockObject + */ + private function createContainerBuilderMock() + { + return $this->getMockBuilder('Symfony\Component\DependencyInjection\ContainerBuilder') + ->disableOriginalConstructor() + ->setMethods(array('hasDefinition', 'setAlias')) + ->getMock(); + } } diff --git a/Tests/DependencyInjection/Compiler/ResourceCompilerPassTest.php b/Tests/DependencyInjection/Compiler/ResourceCompilerPassTest.php index c9dbd56b..dad8b956 100644 --- a/Tests/DependencyInjection/Compiler/ResourceCompilerPassTest.php +++ b/Tests/DependencyInjection/Compiler/ResourceCompilerPassTest.php @@ -43,13 +43,19 @@ public function testTwigResource() { $containerBuilder = $this->createContainerBuilderMock(); $containerBuilder - ->expects($this->any()) - ->method('getParameter') + ->expects($this->exactly(2)) + ->method('hasParameter') ->will($this->returnValueMap(array( - array('templating.engines', array('twig')), - array($parameter = 'twig.form.resources', array($template = 'foo')), + array('templating.helper.form.resources', false), + array($parameter = 'twig.form.resources', true), ))); + $containerBuilder + ->expects($this->once()) + ->method('getParameter') + ->with($this->identicalTo($parameter)) + ->will($this->returnValue(array($template = 'layout.html.twig'))); + $containerBuilder ->expects($this->once()) ->method('setParameter') @@ -65,13 +71,19 @@ public function testPhpResource() { $containerBuilder = $this->createContainerBuilderMock(); $containerBuilder - ->expects($this->any()) - ->method('getParameter') + ->expects($this->exactly(2)) + ->method('hasParameter') ->will($this->returnValueMap(array( - array('templating.engines', array('php')), - array($parameter = 'templating.helper.form.resources', array($template = 'foo')), + array($parameter = 'templating.helper.form.resources', true), + array('twig.form.resources', false), ))); + $containerBuilder + ->expects($this->once()) + ->method('getParameter') + ->with($this->identicalTo($parameter)) + ->will($this->returnValue(array($template = 'layout.html.php'))); + $containerBuilder ->expects($this->once()) ->method('setParameter') @@ -92,7 +104,7 @@ private function createContainerBuilderMock() { return $this->getMockBuilder('Symfony\Component\DependencyInjection\ContainerBuilder') ->disableOriginalConstructor() - ->setMethods(array('getParameter', 'setParameter')) + ->setMethods(array('hasParameter', 'getParameter', 'setParameter')) ->getMock(); } } diff --git a/Tests/DependencyInjection/Compiler/TemplatingCompilerPassTest.php b/Tests/DependencyInjection/Compiler/TemplatingCompilerPassTest.php new file mode 100644 index 00000000..3a9ce5ba --- /dev/null +++ b/Tests/DependencyInjection/Compiler/TemplatingCompilerPassTest.php @@ -0,0 +1,92 @@ + + * + * For the full copyright and license information, please read the LICENSE + * file that was distributed with this source code. + */ + +namespace Ivory\CKEditorBundle\Tests\DependencyInjection\Compiler; + +use Ivory\CKEditorBundle\DependencyInjection\Compiler\TemplatingCompilerPass; + +/** + * Templating compiler pass test. + * + * @author GeLo + */ +class TemplatingCompilerPassTest extends \PHPUnit_Framework_TestCase +{ + /** @var \Ivory\CKEditorBundle\DependencyInjection\Compiler\TemplatingCompilerPass */ + private $compilerPass; + + /** + * {@inheritdoc} + */ + protected function setUp() + { + $this->compilerPass = new TemplatingCompilerPass(); + } + + /** + * {@inheritdoc} + */ + protected function tearDown() + { + unset($this->compilerPass); + } + + public function testPhpTemplating() + { + $containerBuilder = $this->createContainerBuilderMock(); + $containerBuilder + ->expects($this->exactly(2)) + ->method('hasDefinition') + ->will($this->returnValueMap(array( + array('templating.engine.php', false), + array('twig', true), + ))); + + $containerBuilder + ->expects($this->once()) + ->method('removeDefinition') + ->with($this->identicalTo('ivory_ck_editor.templating.helper')); + + $this->compilerPass->process($containerBuilder); + } + + public function testTwigTemplating() + { + $containerBuilder = $this->createContainerBuilderMock(); + $containerBuilder + ->expects($this->exactly(2)) + ->method('hasDefinition') + ->will($this->returnValueMap(array( + array('templating.engine.php', true), + array('twig', false), + ))); + + $containerBuilder + ->expects($this->once()) + ->method('removeDefinition') + ->with($this->identicalTo('ivory_ck_editor.twig_extension')); + + $this->compilerPass->process($containerBuilder); + } + + /** + * Creates a container builder mock. + * + * @return \Symfony\Component\DependencyInjection\ContainerBuilder|\PHPUnit_Framework_MockObject_MockObject The container builder mock. + */ + private function createContainerBuilderMock() + { + return $this->getMockBuilder('Symfony\Component\DependencyInjection\ContainerBuilder') + ->disableOriginalConstructor() + ->setMethods(array('hasDefinition', 'removeDefinition')) + ->getMock(); + } +} diff --git a/Tests/IvoryCKEditorBundleTest.php b/Tests/IvoryCKEditorBundleTest.php index 835b379a..7b41590e 100644 --- a/Tests/IvoryCKEditorBundleTest.php +++ b/Tests/IvoryCKEditorBundleTest.php @@ -21,33 +21,62 @@ */ class IvoryCKEditorBundleTest extends \PHPUnit_Framework_TestCase { - public function testBundle() + /** @var \Ivory\CKEditorBundle\IvoryCKEditorBundle */ + private $bundle; + + /** + * {@inheritdoc} + */ + protected function setUp() { - $bundle = new IvoryCKEditorBundle(); + $this->bundle = new IvoryCKEditorBundle(); + } - $this->assertInstanceOf('Symfony\Component\HttpKernel\Bundle\Bundle', $bundle); + /** + * {@inheritdoc} + */ + protected function tearDown() + { + unset($this->bundle); } - public function testCompilerPasses() + public function testBundle() { - $containerBuilder = $this->getMockBuilder('Symfony\Component\DependencyInjection\ContainerBuilder') - ->disableOriginalConstructor() - ->setMethods(array('addCompilerPass')) - ->getMock(); + $this->assertInstanceOf('Symfony\Component\HttpKernel\Bundle\Bundle', $this->bundle); + } + public function testCompilerPasses() + { + $containerBuilder = $this->createContainerBuilderMock(); $containerBuilder ->expects($this->at(0)) ->method('addCompilerPass') - ->with($this->isInstanceOf('Ivory\CKEditorBundle\DependencyInjection\Compiler\ResourceCompilerPass')) + ->with($this->isInstanceOf('Ivory\CKEditorBundle\DependencyInjection\Compiler\AssetsHelperCompilerPass')) ->will($this->returnSelf()); $containerBuilder ->expects($this->at(1)) ->method('addCompilerPass') - ->with($this->isInstanceOf('Ivory\CKEditorBundle\DependencyInjection\Compiler\AssetsHelperCompilerPass')) + ->with($this->isInstanceOf('Ivory\CKEditorBundle\DependencyInjection\Compiler\ResourceCompilerPass')) + ->will($this->returnSelf()); + + $containerBuilder + ->expects($this->at(2)) + ->method('addCompilerPass') + ->with($this->isInstanceOf('Ivory\CKEditorBundle\DependencyInjection\Compiler\TemplatingCompilerPass')) ->will($this->returnSelf()); - $bundle = new IvoryCKEditorBundle(); - $bundle->build($containerBuilder); + $this->bundle->build($containerBuilder); + } + + /** + * @return \Symfony\Component\DependencyInjection\ContainerBuilder|\PHPUnit_Framework_MockObject_MockObject + */ + private function createContainerBuilderMock() + { + return $this->getMockBuilder('Symfony\Component\DependencyInjection\ContainerBuilder') + ->disableOriginalConstructor() + ->setMethods(array('addCompilerPass')) + ->getMock(); } } diff --git a/Tests/Renderer/CKEditorRendererTest.php b/Tests/Renderer/CKEditorRendererTest.php new file mode 100644 index 00000000..1c734e71 --- /dev/null +++ b/Tests/Renderer/CKEditorRendererTest.php @@ -0,0 +1,399 @@ + + * + * For the full copyright and license information, please read the LICENSE + * file that was distributed with this source code. + */ + +namespace Ivory\CKEditorBundle\Tests\Renderer; + +use Ivory\CKEditorBundle\Renderer\CKEditorRenderer; +use Symfony\Component\DependencyInjection\ContainerInterface; +use Symfony\Component\Routing\RouterInterface; + +/** + * CKEditor renderer test. + * + * @author GeLo + */ +class CKEditorRendererTest extends \PHPUnit_Framework_TestCase +{ + /** @var \Ivory\CKEditorBundle\Renderer\CKEditorRenderer */ + private $renderer; + + /** @var \Symfony\Component\DependencyInjection\ContainerInterface|\PHPUnit_Framework_MockObject_MockObject */ + private $containerMock; + + /** @var \Symfony\Component\Asset\Packages|\Symfony\Component\Templating\Helper\CoreAssetsHelper|\PHPUnit_Framework_MockObject_MockObject */ + private $assetsHelperMock; + + /** @var \Symfony\Component\Routing\RouterInterface|\PHPUnit_Framework_MockObject_MockObject */ + private $routerMock; + + /** + * {@inheritdoc} + */ + protected function setUp() + { + if (class_exists('Symfony\Component\Asset\Packages')) { + $this->assetsHelperMock = $this->getMockBuilder('Symfony\Component\Asset\Packages') + ->disableOriginalConstructor() + ->getMock(); + } else { + $this->assetsHelperMock = $this->getMockBuilder('Symfony\Component\Templating\Helper\CoreAssetsHelper') + ->disableOriginalConstructor() + ->getMock(); + } + + $this->routerMock = $this->getMock('Symfony\Component\Routing\RouterInterface'); + + $this->containerMock = $this->getMock('Symfony\Component\DependencyInjection\ContainerInterface'); + $this->containerMock + ->expects($this->any()) + ->method('get') + ->will($this->returnValueMap(array( + array( + 'assets.packages', + ContainerInterface::NULL_ON_INVALID_REFERENCE, + $this->assetsHelperMock, + ), + array( + 'router', + ContainerInterface::EXCEPTION_ON_INVALID_REFERENCE, + $this->routerMock, + ), + ))); + + $this->renderer = new CKEditorRenderer($this->containerMock); + } + + /** + * {@inheritdoc} + */ + protected function tearDown() + { + unset($this->renderer); + unset($this->containerMock); + unset($this->routerMock); + unset($this->assetsHelperMock); + } + + /** + * Gets the language. + * + * @return array The language. + */ + public function languageProvider() + { + return array( + array('en', 'en'), + array('pt_BR', 'pt-br'), + ); + } + + /** + * Gets the url. + * + * @return array The url. + */ + public function pathProvider() + { + return array( + array('path', 'url', 'url'), + array('path', 'url?v=2', 'url'), + ); + } + + /** + * Gets the urls. + * + * @return array The urls. + */ + public function pathsProvider() + { + return array( + array(array('path'), array('url'), array('url')), + array(array('path'), array('url?v=2'), array('url')), + array(array('path1', 'path2'), array('url1', 'url2'), array('url1', 'url2')), + array(array('path1', 'path2'), array('url1?v=2', 'url2'), array('url1', 'url2')), + array(array('path1', 'path2'), array('url1', 'url2?v=2'), array('url1', 'url2')), + array(array('path1', 'path2'), array('url1?v=2', 'url2?v=2'), array('url1', 'url2')), + ); + } + + /** + * Gets the filebrowsers keys. + * + * @return array The filebrowsers keys. + */ + public function filebrowserProvider() + { + return array( + array('Browse'), + array('FlashBrowse'), + array('ImageBrowse'), + array('ImageBrowseLink'), + array('Upload'), + array('FlashUpload'), + array('ImageUpload'), + ); + } + + public function testDefaultState() + { + $this->assertInstanceOf('Ivory\CKEditorBundle\Renderer\CKEditorRendererInterface', $this->renderer); + } + + /** + * @dataProvider pathProvider + */ + public function testRenderBasePath($path, $asset, $url) + { + $this->assetsHelperMock + ->expects($this->once()) + ->method('getUrl') + ->with($this->equalTo($path)) + ->will($this->returnValue($asset)); + + $this->assertSame($url, $this->renderer->renderBasePath($path)); + } + + public function testRenderJsPath() + { + $this->assetsHelperMock + ->expects($this->once()) + ->method('getUrl') + ->with($this->equalTo('foo')) + ->will($this->returnValue('bar')); + + $this->assertSame('bar', $this->renderer->renderJsPath('foo')); + } + + /** + * @dataProvider languageProvider + */ + public function testRenderWidgetWithLanguage($symfonyLocale, $ckEditorLocale) + { + $this->assertSame( + 'CKEDITOR.replace("foo", {"language":"'.$ckEditorLocale.'"});', + $this->renderer->renderWidget('foo', array('language' => $symfonyLocale)) + ); + } + + /** + * @dataProvider pathProvider + */ + public function testRenderWidgetWithStringContentsCss($path, $asset, $url) + { + $this->assetsHelperMock + ->expects($this->once()) + ->method('getUrl') + ->with($this->equalTo($path)) + ->will($this->returnValue($asset)); + + $this->assertSame( + 'CKEDITOR.replace("foo", {"contentsCss":['.json_encode($url).']});', + $this->renderer->renderWidget('foo', array('contentsCss' => $path)) + ); + } + + /** + * @dataProvider pathsProvider + */ + public function testRenderWidgetWithArrayContentsCss(array $paths, array $assets, array $urls) + { + foreach (array_keys($paths) as $key) { + $this->assetsHelperMock + ->expects($this->at($key)) + ->method('getUrl') + ->with($this->equalTo($paths[$key])) + ->will($this->returnValue($assets[$key])); + } + + $this->assertSame( + 'CKEDITOR.replace("foo", {"contentsCss":'.json_encode($urls).'});', + $this->renderer->renderWidget('foo', array('contentsCss' => $paths)) + ); + } + + /** + * @dataProvider filebrowserProvider + */ + public function testRenderWidgetWithFileBrowser($filebrowser) + { + $this->routerMock + ->expects($this->once()) + ->method('generate') + ->with( + $this->equalTo('browse_route'), + $this->equalTo(array('foo' => 'bar')), + $this->equalTo(true) + ) + ->will($this->returnValue('browse_url')); + + $this->assertSame( + 'CKEDITOR.replace("foo", {"filebrowser'.$filebrowser.'Url":"browse_url"});', + $this->renderer->renderWidget('foo', array( + 'filebrowser'.$filebrowser.'Route' => 'browse_route', + 'filebrowser'.$filebrowser.'RouteParameters' => array('foo' => 'bar'), + 'filebrowser'.$filebrowser.'RouteAbsolute' => true, + )) + ); + } + + /** + * @dataProvider filebrowserProvider + */ + public function testRenderWidgetWithFileBrowserHandler($filebrowser) + { + $this->routerMock + ->expects($this->once()) + ->method('generate') + ->with( + $this->equalTo('browse_route'), + $this->equalTo(array('foo' => 'bar')), + $this->equalTo(true) + ) + ->will($this->returnValue('browse_url')); + + $this->assertSame( + 'CKEDITOR.replace("foo", {"filebrowser'.$filebrowser.'Url":"browse_url"});', + $this->renderer->renderWidget('foo', array( + 'filebrowser'.$filebrowser.'Handler' => function (RouterInterface $router) { + return $router->generate('browse_route', array('foo' => 'bar'), true); + }, + )) + ); + } + + public function testRenderWidgetWithProtectedSource() + { + $this->assertSame( + 'CKEDITOR.replace("foo", {"protectedSource":[/<\?[\s\S]*?\?>/g,/<%[\s\S]*?%>/g]});', + $this->renderer->renderWidget('foo', array( + 'protectedSource' => array( + '/<\?[\s\S]*?\?>/g', + '/<%[\s\S]*?%>/g', + ), + )) + ); + } + + public function testRenderWidgetWithStylesheetParserSkipSelectors() + { + $this->assertSame( + 'CKEDITOR.replace("foo", {"stylesheetParser_skipSelectors":/(^body\.|^caption\.|\.high|^\.)/i});', + $this->renderer->renderWidget('foo', array( + 'stylesheetParser_skipSelectors' => '/(^body\.|^caption\.|\.high|^\.)/i', + )) + ); + } + + public function testRenderWidgetWithStylesheetParserValidSelectors() + { + $this->assertSame( + 'CKEDITOR.replace("foo", {"stylesheetParser_validSelectors":/\^(p|span)\.\w+/});', + $this->renderer->renderWidget('foo', array( + 'stylesheetParser_validSelectors' => '/\^(p|span)\.\w+/', + )) + ); + } + + public function testRenderWidgetWithCKEditorConstants() + { + $this->assertSame( + 'CKEDITOR.replace("foo", {"config":{"enterMode":CKEDITOR.ENTER_BR,"shiftEnterMode":CKEDITOR.ENTER_BR}});', + $this->renderer->renderWidget('foo', array( + 'config' => array( + 'enterMode' => 'CKEDITOR.ENTER_BR', + 'shiftEnterMode' => 'CKEDITOR.ENTER_BR', + ), + )) + ); + } + + public function testRenderWidgetWithoutAutoInline() + { + $expected = <<assertSame( + $expected, + $this->renderer->renderWidget('foo', array(), array('auto_inline' => false)) + ); + } + + public function testRenderWidgetWithInline() + { + $this->assertSame( + 'CKEDITOR.inline("foo", []);', + $this->renderer->renderWidget('foo', array(), array('inline' => true)) + ); + } + + public function testRenderWidgetWithInputSync() + { + $expected = <<assertSame($expected, $this->renderer->renderWidget('foo', array(), array('input_sync' => true))); + } + + public function testRenderDestroy() + { + $this->assertSame( + 'if (CKEDITOR.instances["foo"]) { delete CKEDITOR.instances["foo"]; }', + $this->renderer->renderDestroy('foo') + ); + } + + /** + * @dataProvider pathProvider + */ + public function testRenderPlugin($path, $asset, $url) + { + $this->assetsHelperMock + ->expects($this->once()) + ->method('getUrl') + ->with($this->equalTo($path)) + ->will($this->returnValue($asset)); + + $this->assertSame( + 'CKEDITOR.plugins.addExternal("foo", '.json_encode($url).', "bat");', + $this->renderer->renderPlugin('foo', array('path' => $path, 'filename' => 'bat')) + ); + } + + public function testRenderStylesSet() + { + $this->assertSame( + 'if (CKEDITOR.stylesSet.get("foo") === null) { CKEDITOR.stylesSet.add("foo", {"foo":"bar"}); }', + $this->renderer->renderStylesSet('foo', array('foo' => 'bar')) + ); + } + + /** + * @dataProvider pathProvider + */ + public function testRenderTemplate($path, $asset, $url) + { + $this->assetsHelperMock + ->expects($this->once()) + ->method('getUrl') + ->with($this->equalTo($path)) + ->will($this->returnValue($asset)); + + $this->assertSame( + 'CKEDITOR.addTemplates("foo", {"imagesPath":'.json_encode($url).',"filename":"bat"});', + $this->renderer->renderTemplate('foo', array('imagesPath' => $path, 'filename' => 'bat')) + ); + } +} diff --git a/Tests/Template/AbstractTemplateTest.php b/Tests/Template/AbstractTemplateTest.php index 976e5d2f..c5bb3209 100644 --- a/Tests/Template/AbstractTemplateTest.php +++ b/Tests/Template/AbstractTemplateTest.php @@ -11,7 +11,7 @@ namespace Ivory\CKEditorBundle\Tests\Template; -use Ivory\CKEditorBundle\Templating\CKEditorHelper; +use Ivory\CKEditorBundle\Renderer\CKEditorRenderer; use Symfony\Component\DependencyInjection\ContainerInterface; /** @@ -22,8 +22,8 @@ */ abstract class AbstractTemplateTest extends \PHPUnit_Framework_TestCase { - /** @var \Ivory\CKEditorBundle\Templating\CKEditorHelper */ - protected $helper; + /** @var \Ivory\CKEditorBundle\Renderer\CKEditorRenderer */ + protected $renderer; /** @var \Symfony\Component\DependencyInjection\ContainerInterface|\PHPUnit_Framework_MockObject_MockObject */ private $containerMock; @@ -73,7 +73,7 @@ protected function setUp() ), ))); - $this->helper = new CKEditorHelper($this->containerMock); + $this->renderer = new CKEditorRenderer($this->containerMock); } /** @@ -84,7 +84,12 @@ protected function tearDown() unset($this->routerMock); unset($this->assetsHelperMock); unset($this->containerMock); - unset($this->helper); + unset($this->renderer); + } + + public function testDefaultState() + { + $this->assertInstanceOf('Ivory\CKEditorBundle\Renderer\CKEditorRendererInterface', $this->renderer); } public function testRenderWithSimpleWidget() diff --git a/Tests/Template/PhpTemplateTest.php b/Tests/Template/PhpTemplateTest.php index 8b849775..ca5a5c1b 100644 --- a/Tests/Template/PhpTemplateTest.php +++ b/Tests/Template/PhpTemplateTest.php @@ -11,6 +11,7 @@ namespace Ivory\CKEditorBundle\Tests\Template; +use Ivory\CKEditorBundle\Templating\CKEditorHelper; use Symfony\Component\Templating\Loader\FilesystemLoader; use Symfony\Component\Templating\PhpEngine; use Symfony\Component\Templating\TemplateNameParser; @@ -52,7 +53,7 @@ protected function setUp() array( 'form' => $this->formHelperMock, 'slots' => $this->slotsHelperMock, - $this->helper, + new CKEditorHelper($this->renderer), ) ); } diff --git a/Tests/Template/TwigTemplateTest.php b/Tests/Template/TwigTemplateTest.php index 3048e34b..9230aa3e 100644 --- a/Tests/Template/TwigTemplateTest.php +++ b/Tests/Template/TwigTemplateTest.php @@ -34,7 +34,7 @@ protected function setUp() parent::setUp(); $this->twig = new \Twig_Environment(new \Twig_Loader_Filesystem(array(__DIR__.'/../../Resources/views/Form'))); - $this->twig->addExtension(new CKEditorExtension($this->helper)); + $this->twig->addExtension(new CKEditorExtension($this->renderer)); $this->template = $this->twig->loadTemplate('ckeditor_widget.html.twig'); } diff --git a/Tests/Templating/CKEditorHelperTest.php b/Tests/Templating/CKEditorHelperTest.php index 27204d6e..84fcb9e8 100644 --- a/Tests/Templating/CKEditorHelperTest.php +++ b/Tests/Templating/CKEditorHelperTest.php @@ -12,389 +12,32 @@ namespace Ivory\CKEditorBundle\Tests\Templating; use Ivory\CKEditorBundle\Templating\CKEditorHelper; -use Symfony\Component\DependencyInjection\ContainerInterface; -use Symfony\Component\Routing\RouterInterface; /** * CKEditor helper test. * * @author GeLo - * @author Adam Misiorny */ class CKEditorHelperTest extends \PHPUnit_Framework_TestCase { - /** @var \Ivory\CKEditorBundle\Templating\CKEditorHelper */ - private $helper; - - /** @var \Symfony\Component\DependencyInjection\ContainerInterface|\PHPUnit_Framework_MockObject_MockObject */ - private $containerMock; - - /** @var \Symfony\Component\Asset\Packages|\Symfony\Component\Templating\Helper\CoreAssetsHelper|\PHPUnit_Framework_MockObject_MockObject */ - private $assetsHelperMock; - - /** @var \Symfony\Component\Routing\RouterInterface|\PHPUnit_Framework_MockObject_MockObject */ - private $routerMock; - - /** - * {@inheritdoc} - */ - protected function setUp() - { - if (class_exists('Symfony\Component\Asset\Packages')) { - $this->assetsHelperMock = $this->getMockBuilder('Symfony\Component\Asset\Packages') - ->disableOriginalConstructor() - ->getMock(); - } else { - $this->assetsHelperMock = $this->getMockBuilder('Symfony\Component\Templating\Helper\CoreAssetsHelper') - ->disableOriginalConstructor() - ->getMock(); - } - - $this->routerMock = $this->getMock('Symfony\Component\Routing\RouterInterface'); - - $this->containerMock = $this->getMock('Symfony\Component\DependencyInjection\ContainerInterface'); - $this->containerMock - ->expects($this->any()) - ->method('get') - ->will($this->returnValueMap(array( - array( - 'assets.packages', - ContainerInterface::NULL_ON_INVALID_REFERENCE, - $this->assetsHelperMock, - ), - array( - 'router', - ContainerInterface::EXCEPTION_ON_INVALID_REFERENCE, - $this->routerMock, - ), - ))); - - $this->helper = new CKEditorHelper($this->containerMock); - } - - /** - * {@inheritdoc} - */ - protected function tearDown() - { - unset($this->helper); - unset($this->containerMock); - unset($this->routerMock); - unset($this->assetsHelperMock); - } - - /** - * Gets the language. - * - * @return array The language. - */ - public function languageProvider() - { - return array( - array('en', 'en'), - array('pt_BR', 'pt-br'), - ); - } - - /** - * Gets the url. - * - * @return array The url. - */ - public function pathProvider() - { - return array( - array('path', 'url', 'url'), - array('path', 'url?v=2', 'url'), - ); - } - - /** - * Gets the urls. - * - * @return array The urls. - */ - public function pathsProvider() + public function testLegacyContainerConstructor() { - return array( - array(array('path'), array('url'), array('url')), - array(array('path'), array('url?v=2'), array('url')), - array(array('path1', 'path2'), array('url1', 'url2'), array('url1', 'url2')), - array(array('path1', 'path2'), array('url1?v=2', 'url2'), array('url1', 'url2')), - array(array('path1', 'path2'), array('url1', 'url2?v=2'), array('url1', 'url2')), - array(array('path1', 'path2'), array('url1?v=2', 'url2?v=2'), array('url1', 'url2')), - ); - } - - /** - * Gets the filebrowsers keys. - * - * @return array The filebrowsers keys. - */ - public function filebrowserProvider() - { - return array( - array('Browse'), - array('FlashBrowse'), - array('ImageBrowse'), - array('ImageBrowseLink'), - array('Upload'), - array('FlashUpload'), - array('ImageUpload'), - ); - } - - /** - * @dataProvider pathProvider - */ - public function testRenderBasePath($path, $asset, $url) - { - $this->assetsHelperMock - ->expects($this->once()) - ->method('getUrl') - ->with($this->equalTo($path)) - ->will($this->returnValue($asset)); - - $this->assertSame($url, $this->helper->renderBasePath($path)); - } - - public function testRenderJsPath() - { - $this->assetsHelperMock + $container = $this->getMock('Symfony\Component\DependencyInjection\ContainerInterface'); + $container ->expects($this->once()) - ->method('getUrl') - ->with($this->equalTo('foo')) - ->will($this->returnValue('bar')); - - $this->assertSame('bar', $this->helper->renderJsPath('foo')); - } - - /** - * @dataProvider languageProvider - */ - public function testRenderWidgetWithLanguage($symfonyLocale, $ckEditorLocale) - { - $this->assertSame( - 'CKEDITOR.replace("foo", {"language":"'.$ckEditorLocale.'"});', - $this->helper->renderWidget('foo', array('language' => $symfonyLocale)) - ); - } - - /** - * @dataProvider pathProvider - */ - public function testRenderWidgetWithStringContentsCss($path, $asset, $url) - { - $this->assetsHelperMock - ->expects($this->once()) - ->method('getUrl') - ->with($this->equalTo($path)) - ->will($this->returnValue($asset)); - - $this->assertSame( - 'CKEDITOR.replace("foo", {"contentsCss":['.json_encode($url).']});', - $this->helper->renderWidget('foo', array('contentsCss' => $path)) - ); - } - - /** - * @dataProvider pathsProvider - */ - public function testRenderWidgetWithArrayContentsCss(array $paths, array $assets, array $urls) - { - foreach (array_keys($paths) as $key) { - $this->assetsHelperMock - ->expects($this->at($key)) - ->method('getUrl') - ->with($this->equalTo($paths[$key])) - ->will($this->returnValue($assets[$key])); - } - - $this->assertSame( - 'CKEDITOR.replace("foo", {"contentsCss":'.json_encode($urls).'});', - $this->helper->renderWidget('foo', array('contentsCss' => $paths)) - ); - } - - /** - * @dataProvider filebrowserProvider - */ - public function testRenderWidgetWithFileBrowser($filebrowser) - { - $this->routerMock - ->expects($this->once()) - ->method('generate') - ->with( - $this->equalTo('browse_route'), - $this->equalTo(array('foo' => 'bar')), - $this->equalTo(true) - ) - ->will($this->returnValue('browse_url')); - - $this->assertSame( - 'CKEDITOR.replace("foo", {"filebrowser'.$filebrowser.'Url":"browse_url"});', - $this->helper->renderWidget('foo', array( - 'filebrowser'.$filebrowser.'Route' => 'browse_route', - 'filebrowser'.$filebrowser.'RouteParameters' => array('foo' => 'bar'), - 'filebrowser'.$filebrowser.'RouteAbsolute' => true, - )) - ); - } - - /** - * @dataProvider filebrowserProvider - */ - public function testRenderWidgetWithFileBrowserHandler($filebrowser) - { - $this->routerMock - ->expects($this->once()) - ->method('generate') - ->with( - $this->equalTo('browse_route'), - $this->equalTo(array('foo' => 'bar')), - $this->equalTo(true) - ) - ->will($this->returnValue('browse_url')); - - $this->assertSame( - 'CKEDITOR.replace("foo", {"filebrowser'.$filebrowser.'Url":"browse_url"});', - $this->helper->renderWidget('foo', array( - 'filebrowser'.$filebrowser.'Handler' => function (RouterInterface $router) { - return $router->generate('browse_route', array('foo' => 'bar'), true); - }, - )) - ); - } - - public function testRenderWidgetWithProtectedSource() - { - $this->assertSame( - 'CKEDITOR.replace("foo", {"protectedSource":[/<\?[\s\S]*?\?>/g,/<%[\s\S]*?%>/g]});', - $this->helper->renderWidget('foo', array( - 'protectedSource' => array( - '/<\?[\s\S]*?\?>/g', - '/<%[\s\S]*?%>/g', - ), - )) - ); - } - - public function testRenderWidgetWithStylesheetParserSkipSelectors() - { - $this->assertSame( - 'CKEDITOR.replace("foo", {"stylesheetParser_skipSelectors":/(^body\.|^caption\.|\.high|^\.)/i});', - $this->helper->renderWidget('foo', array( - 'stylesheetParser_skipSelectors' => '/(^body\.|^caption\.|\.high|^\.)/i', - )) - ); - } - - public function testRenderWidgetWithStylesheetParserValidSelectors() - { - $this->assertSame( - 'CKEDITOR.replace("foo", {"stylesheetParser_validSelectors":/\^(p|span)\.\w+/});', - $this->helper->renderWidget('foo', array( - 'stylesheetParser_validSelectors' => '/\^(p|span)\.\w+/', - )) - ); - } - - public function testRenderWidgetWithCKEditorConstants() - { - $this->assertSame( - 'CKEDITOR.replace("foo", {"config":{"enterMode":CKEDITOR.ENTER_BR,"shiftEnterMode":CKEDITOR.ENTER_BR}});', - $this->helper->renderWidget('foo', array( - 'config' => array( - 'enterMode' => 'CKEDITOR.ENTER_BR', - 'shiftEnterMode' => 'CKEDITOR.ENTER_BR', - ), - )) - ); - } - - public function testRenderWidgetWithoutAutoInline() - { - $expected = <<assertSame( - $expected, - $this->helper->renderWidget('foo', array(), array('auto_inline' => false)) - ); - } - - public function testRenderWidgetWithInline() - { - $this->assertSame( - 'CKEDITOR.inline("foo", []);', - $this->helper->renderWidget('foo', array(), array('inline' => true)) - ); - } - - public function testRenderWidgetWithInputSync() - { - $expected = <<assertSame($expected, $this->helper->renderWidget('foo', array(), array('input_sync' => true))); - } - - public function testRenderDestroy() - { - $this->assertSame( - 'if (CKEDITOR.instances["foo"]) { delete CKEDITOR.instances["foo"]; }', - $this->helper->renderDestroy('foo') - ); - } - - /** - * @dataProvider pathProvider - */ - public function testRenderPlugin($path, $asset, $url) - { - $this->assetsHelperMock - ->expects($this->once()) - ->method('getUrl') - ->with($this->equalTo($path)) - ->will($this->returnValue($asset)); - - $this->assertSame( - 'CKEDITOR.plugins.addExternal("foo", '.json_encode($url).', "bat");', - $this->helper->renderPlugin('foo', array('path' => $path, 'filename' => 'bat')) - ); - } + ->method('get') + ->with($this->identicalTo('ivory_ck_editor.renderer')) + ->will($this->returnValue($this->getMock('Ivory\CKEditorBundle\Renderer\CKEditorRendererInterface'))); - public function testRenderStylesSet() - { - $this->assertSame( - 'if (CKEDITOR.stylesSet.get("foo") === null) { CKEDITOR.stylesSet.add("foo", {"foo":"bar"}); }', - $this->helper->renderStylesSet('foo', array('foo' => 'bar')) - ); + new CKEditorHelper($container); } /** - * @dataProvider pathProvider + * @expectedException \InvalidArgumentException + * @expectedExceptionMessage The CKEditor renderer must be an instance of "Ivory\CKEditorBundle\Renderer\CKEditorRendererInterface". */ - public function testRenderTemplate($path, $asset, $url) - { - $this->assetsHelperMock - ->expects($this->once()) - ->method('getUrl') - ->with($this->equalTo($path)) - ->will($this->returnValue($asset)); - - $this->assertSame( - 'CKEDITOR.addTemplates("foo", {"imagesPath":'.json_encode($url).',"filename":"bat"});', - $this->helper->renderTemplate('foo', array('imagesPath' => $path, 'filename' => 'bat')) - ); - } - - public function testName() + public function testInvalidRendererConstructor() { - $this->assertSame('ivory_ckeditor', $this->helper->getName()); + new CKEditorHelper(new \stdClass()); } } diff --git a/Twig/CKEditorExtension.php b/Twig/CKEditorExtension.php index 27b94ea1..b97b5eba 100644 --- a/Twig/CKEditorExtension.php +++ b/Twig/CKEditorExtension.php @@ -11,26 +11,27 @@ namespace Ivory\CKEditorBundle\Twig; +use Ivory\CKEditorBundle\Renderer\CKEditorRendererInterface; use Ivory\CKEditorBundle\Templating\CKEditorHelper; /** - * CKEditorExtension + * CKEditor Twig extension. * * @author GeLo */ -class CKEditorExtension extends \Twig_Extension +class CKEditorExtension extends \Twig_Extension implements CKEditorRendererInterface { - /** @var \Ivory\CKEditorBundle\Templating\CKEditorHelper */ - private $helper; + /** @var \Ivory\CKEditorBundle\Renderer\CKEditorRendererInterface */ + private $renderer; /** - * Creates a CKEditor extension. + * Creates a CKEditor Twig extension. * - * @param \Ivory\CKEditorBundle\Templating\CKEditorHelper $helper The CKEditor helper. + * @param \Ivory\CKEditorBundle\Renderer\CKEditorRendererInterface $renderer The CKEditor renderer. */ - public function __construct(CKEditorHelper $helper) + public function __construct(CKEditorRendererInterface $renderer) { - $this->helper = $helper; + $this->renderer = $renderer; } /** @@ -52,92 +53,59 @@ public function getFunctions() } /** - * Renders the base path. - * - * @param string $basePath The base path. - * - * @return string The rendered base path. + * {@inheritdoc} */ public function renderBasePath($basePath) { - return $this->helper->renderBasePath($basePath); + return $this->renderer->renderBasePath($basePath); } /** - * Renders the js path. - * - * @param string $jsPath The js path. - * - * @return string The rendered js path. + * {@inheritdoc} */ public function renderJsPath($jsPath) { - return $this->helper->renderJsPath($jsPath); + return $this->renderer->renderJsPath($jsPath); } /** - * Renders the widget. - * - * @param string $id The identifier. - * @param array $config The config. - * @param array $options The options. - * - * @return string The rendered widget. + * {@inheritdoc} */ public function renderWidget($id, array $config, array $options = array()) { - return $this->helper->renderWidget($id, $config, $options); + return $this->renderer->renderWidget($id, $config, $options); } /** - * Renders the destroy. - * - * @param string $id The identifier. - * - * @return string The rendered destroy. + * {@inheritdoc} */ public function renderDestroy($id) { - return $this->helper->renderDestroy($id); + return $this->renderer->renderDestroy($id); } /** - * Renders a plugin. - * - * @param string $name The name. - * @param array $plugin The plugin. - * - * @return string The rendered plugin. + * {@inheritdoc} */ public function renderPlugin($name, array $plugin) { - return $this->helper->renderPlugin($name, $plugin); + return $this->renderer->renderPlugin($name, $plugin); } /** - * Renders a styles set. - * - * @param string $name The name - * @param array $stylesSet The style set. - * - * @return string The rendered style set. + * {@inheritdoc} */ public function renderStylesSet($name, array $stylesSet) { - return $this->helper->renderStylesSet($name, $stylesSet); + return $this->renderer->renderStylesSet($name, $stylesSet); } /** - * Renders a template. - * - * @param string $name The template name. - * @param array $template The template. - * - * @return string The rendered template. + * {@inheritdoc} */ public function renderTemplate($name, array $template) { - return $this->helper->renderTemplate($name, $template); + return $this->renderer->renderTemplate($name, $template); } /** @@ -145,6 +113,6 @@ public function renderTemplate($name, array $template) */ public function getName() { - return $this->helper->getName(); + return 'ivory_ckeditor'; } }