| 1: | <?php |
| 2: | namespace TIC\FormBundle\Form\Type; |
| 3: | |
| 4: | |
| 5: | use TIC\FormBundle\Base\TICWidgetType as BaseType; |
| 6: | |
| 7: | use Symfony\Component\OptionsResolver\OptionsResolver; |
| 8: | use Symfony\Component\Form\FormBuilderInterface; |
| 9: | use Symfony\Component\Form\FormInterface; |
| 10: | use Symfony\Component\Form\FormView; |
| 11: | |
| 12: | use Symfony\Component\Form\CallbackTransformer; |
| 13: | |
| 14: | |
| 15: | |
| 16: | |
| 17: | |
| 18: | class EditorType extends BaseType |
| 19: | { |
| 20: | |
| 21: | |
| 22: | |
| 23: | |
| 24: | |
| 25: | |
| 26: | public function configureOptions(OptionsResolver $resolver): void |
| 27: | { |
| 28: | parent::configureOptions($resolver); |
| 29: | |
| 30: | $resolver->setDefaults(array( |
| 31: | 'compound' => false, |
| 32: | 'wysiwyg' => false, |
| 33: | 'rows' => 2, |
| 34: | 'height' => null, |
| 35: | 'focus' => false, |
| 36: | 'allowLinks' => true, |
| 37: | 'allowTable' => true, |
| 38: | 'allowImage' => true, |
| 39: | 'allowVideo' => true, |
| 40: | 'toolbars' => true, |
| 41: | 'language' => \Locale::getPrimaryLanguage(\Locale::getDefault()), |
| 42: | )); |
| 43: | |
| 44: | $resolver->setAllowedTypes('wysiwyg', array('bool')); |
| 45: | $resolver->setAllowedTypes('rows', array('int')); |
| 46: | $resolver->setAllowedTypes('height', array('int', 'null')); |
| 47: | $resolver->setAllowedTypes('focus', array('bool')); |
| 48: | $resolver->setAllowedTypes('allowLinks', array('bool')); |
| 49: | $resolver->setAllowedTypes('allowTable', array('bool')); |
| 50: | $resolver->setAllowedTypes('allowImage', array('bool')); |
| 51: | $resolver->setAllowedTypes('allowVideo', array('bool')); |
| 52: | $resolver->setAllowedTypes('toolbars', array('array', 'string', 'bool', 'null')); |
| 53: | $resolver->setAllowedTypes('language', array('string', 'null')); |
| 54: | } |
| 55: | |
| 56: | |
| 57: | |
| 58: | |
| 59: | |
| 60: | public function buildForm(FormBuilderInterface $builder, array $options): void |
| 61: | { |
| 62: | $builder->addModelTransformer(new CallbackTransformer( |
| 63: | function ($populatedText) { |
| 64: | return $populatedText; |
| 65: | }, |
| 66: | function ($submittedText) { |
| 67: | |
| 68: | $content = strip_tags(str_replace(' ', '', $submittedText), '<img>'); |
| 69: | |
| 70: | return strlen(trim($content)) ? $submittedText : NULL; |
| 71: | } |
| 72: | )); |
| 73: | } |
| 74: | |
| 75: | |
| 76: | |
| 77: | |
| 78: | |
| 79: | public function buildView(FormView $view, FormInterface $form, array $options): void |
| 80: | { |
| 81: | parent::buildView($view, $form, $options); |
| 82: | |
| 83: | |
| 84: | $view->vars['wysiwyg'] = false; |
| 85: | if ($options['focus']) $view->vars['attr']['autofocus'] = true; |
| 86: | if ($options['height']) $view->vars['attr']['rows'] = max(2, round($options['height'] / 22)); |
| 87: | elseif ($options['rows']) $view->vars['attr']['rows'] = max(2, intval($options['rows'])); |
| 88: | |
| 89: | |
| 90: | if ($options['wysiwyg'] && ! $options['disabled']) { |
| 91: | $view->vars['wysiwyg'] = true; |
| 92: | $view->vars['focus'] = $options['focus']; |
| 93: | $view->vars['lang'] = $this->getLang($options['language']); |
| 94: | $view->vars['toolbars'] = $this->makeToolbars($options); |
| 95: | if ($options['height']) $view->vars['height'] = max(50, intval($options['height'])); |
| 96: | elseif ($options['rows']) $view->vars['height'] = max(50, intval($options['rows'])*22); |
| 97: | } |
| 98: | } |
| 99: | |
| 100: | |
| 101: | |
| 102: | |
| 103: | |
| 104: | private function getLang($language): ?string |
| 105: | { |
| 106: | if (! is_string($language)) return null; |
| 107: | list($code) = explode('_', strtolower($language) . '_'); |
| 108: | switch ($code) { |
| 109: | case 'en' : return null; |
| 110: | case 'fr' : return 'fr-FR'; |
| 111: | case 'de' : return 'de-DE'; |
| 112: | case 'es' : return 'es-ES'; |
| 113: | case 'it' : return 'it-IT'; |
| 114: | case 'pt' : return 'pt-PT'; |
| 115: | case 'ru' : return 'ru-RU'; |
| 116: | case 'ja' : return 'ja-JP'; |
| 117: | case 'zh' : return 'zh-CN'; |
| 118: | case 'ar' : return 'ar-AR'; |
| 119: | case 'bg' : return 'bg-BG'; |
| 120: | case 'ca' : return 'ca-ES'; |
| 121: | case 'cs' : return 'cs-CZ'; |
| 122: | case 'da' : return 'da-DK'; |
| 123: | case 'eu' : return 'es-EU'; |
| 124: | case 'fa' : return 'fa-IR'; |
| 125: | case 'fu' : return 'fi-FI'; |
| 126: | case 'gl' : return 'gl-ES'; |
| 127: | case 'he' : return 'he-IL'; |
| 128: | case 'hr' : return 'hr-HR'; |
| 129: | case 'hu' : return 'hu-HU'; |
| 130: | case 'id' : return 'id-ID'; |
| 131: | case 'ko' : return 'ko-KR'; |
| 132: | case 'lt' : return 'lt-LT'; |
| 133: | case 'lv' : return 'lt-LV'; |
| 134: | case 'nb' : return 'nb-NO'; |
| 135: | case 'no' : return 'nb-NO'; |
| 136: | case 'nl' : return 'nl-NL'; |
| 137: | case 'pl' : return 'pl-PL'; |
| 138: | |
| 139: | case 'ro' : return 'ro-RO'; |
| 140: | case 'sk' : return 'sk-SK'; |
| 141: | case 'sl' : return 'sl-SI'; |
| 142: | case 'sr' : return 'sr-RS'; |
| 143: | case 'sv' : return 'sv-SE'; |
| 144: | case 'th' : return 'th-TH'; |
| 145: | case 'tr' : return 'tr-TR'; |
| 146: | case 'ok' : return 'uk-UA'; |
| 147: | case 'vi' : return 'vi-VN'; |
| 148: | |
| 149: | } |
| 150: | } |
| 151: | |
| 152: | |
| 153: | |
| 154: | |
| 155: | |
| 156: | private function makeToolbars($options) |
| 157: | { |
| 158: | $bars = isset($options['toolbars']) ? $options['toolbars'] : null; |
| 159: | |
| 160: | if ($bars === null) return; |
| 161: | if ($bars === false) return array(); |
| 162: | |
| 163: | if ($bars === true) $bars = array('history','fontfull','stylefull','parafull','table','insert','view'); |
| 164: | elseif (is_string($bars)) $bars = explode(',', $bars); |
| 165: | elseif (! is_array($bars)) return; |
| 166: | |
| 167: | $presets = array( |
| 168: | 'history' => array('undo', 'redo'), |
| 169: | |
| 170: | 'style' => array('style'), |
| 171: | 'font' => array('bold', 'underline', 'clear'), |
| 172: | 'fontstyle' => array('bold', 'italic', 'underline', 'clear'), |
| 173: | 'fontstyles' => array('bold', 'italic', 'underline', 'strikethrough', 'clear'), |
| 174: | 'fontmore' => array('strikethrough', 'superscript', 'subscript'), |
| 175: | 'stylefull' => array('style', 'bold', 'italic', 'underline', 'strikethrough', 'clear'), |
| 176: | |
| 177: | 'fontname' => array('fontname'), |
| 178: | 'fontsize' => array('fontsize'), |
| 179: | 'color' => array('color'), |
| 180: | 'fontfull' => array('fontname', 'fontsize', 'color'), |
| 181: | |
| 182: | 'para' => array('ul', 'ol', 'paragraph'), |
| 183: | 'parafull' => array('paragraph', 'height', 'ol', 'ul', 'listStyles', 'hr'), |
| 184: | 'paragraph' => array('paragraph'), |
| 185: | 'height' => array('height'), |
| 186: | 'list' => array('ol', 'ul', 'listStyles'), |
| 187: | |
| 188: | 'table' => array('table'), |
| 189: | |
| 190: | 'insert' => array('link', 'picture', 'video'), |
| 191: | 'media' => array('picture', 'video'), |
| 192: | 'image' => array('picture'), |
| 193: | 'video' => array('video'), |
| 194: | 'link' => array('link'), |
| 195: | |
| 196: | 'view' => array('fullscreen', 'codeview', 'help'), |
| 197: | 'fullscreen' => array('fullscreen'), |
| 198: | 'source' => array('codeview'), |
| 199: | 'help' => array('help'), |
| 200: | ); |
| 201: | |
| 202: | $excludes = array(); |
| 203: | if (! $options['allowLinks']) $excludes[] = 'link'; |
| 204: | if (! $options['allowTable']) $excludes[] = 'table'; |
| 205: | if (! $options['allowImage']) $excludes[] = 'picture'; |
| 206: | if (! $options['allowVideo']) $excludes[] = 'video'; |
| 207: | |
| 208: | $toolbars = array(); |
| 209: | foreach ($bars as $bar) { |
| 210: | $key = strtolower(trim($bar)); |
| 211: | if (! isset($presets[$key])) continue; |
| 212: | $tools = array_values(array_diff($presets[$key], $excludes)); |
| 213: | if (count($tools)) $toolbars[] = array($key, $tools); |
| 214: | } |
| 215: | return $toolbars; |
| 216: | } |
| 217: | |
| 218: | |
| 219: | } |
| 220: | |