Overview

Packages

  • CONTENIDO
  • Core
    • Authentication
    • Backend
    • Cache
    • CEC
    • Chain
    • ContentType
    • Database
    • Debug
    • Exception
    • Frontend
      • Search
      • URI
      • Util
    • GenericDB
      • Model
    • GUI
      • HTML
    • I18N
    • LayoutHandler
    • Log
    • Security
    • Session
    • Util
    • Validation
    • Versioning
    • XML
  • Module
    • ContentRssCreator
    • ContentSitemapHtml
    • ContentSitemapXml
    • ContentUserForum
    • NavigationTop
    • ScriptCookieDirective
  • mpAutoloaderClassMap
  • None
  • Plugin
    • ContentAllocation
    • CronjobOverview
    • FormAssistant
    • FrontendLogic
    • FrontendUsers
    • Linkchecker
    • ModRewrite
    • Newsletter
    • Repository
      • FrontendNavigation
      • KeywordDensity
    • SearchSolr
    • SmartyWrapper
    • UrlShortener
    • UserForum
    • Workflow
  • PluginManager
  • Setup
    • Form
    • GUI
    • Helper
      • Environment
      • Filesystem
      • MySQL
      • PHP
    • UpgradeJob

Classes

  • cAjaxRequest
  • cAutoload
  • cBackend
  • cEffectiveSetting
  • cGuiScrollListAlltranslations
  • cHTMLValidator
  • cMailer
  • cModuleFileTranslation
  • cModuleHandler
  • cModuleSearch
  • cModuleSynchronizer
  • cModuleTemplateHandler
  • CodeMirror
  • cPasswordRequest
  • cPermission
  • cRegistry
  • cSystemPurge
  • cSystemtest
  • cTinymce4Configuration
  • cTinyMCE4Editor
  • cTinyMCEEditor
  • cWYSIWYGEditor
  • FrontendList
  • HtmlParser
  • TODOBackendList
  • TreeItem
  • UploadList
  • UploadSearchResultList

Functions

  • addArtspec
  • addSortImages
  • backToMainArea
  • buildArticleSelect
  • buildCategorySelect
  • buildCategorySelectRights
  • buildHeapTable
  • buildStackString
  • buildTree
  • buildUserOrGroupPermsFromRequest
  • callPluginStore
  • cApiCatGetLevelNode
  • cApiImageCheckCachedImageValidity
  • cApiImageCheckImageEditingPosibility
  • cApiImageGetCacheFileName
  • cApiImageGetTargetDimensions
  • cApiImageIsAnimGif
  • cApiImgScale
  • cApiImgScaleGetMD5CacheFile
  • cApiImgScaleHQ
  • cApiImgScaleImageMagick
  • cApiImgScaleLQ
  • cApiIsImageMagickAvailable
  • cApiStrCleanURLCharacters
  • cApiStrNormalizeLineEndings
  • cApiStrRecodeString
  • cApiStrReplaceDiacritics
  • cApiStrTrimAfterWord
  • cApiStrTrimHard
  • cApiStrTrimSentence
  • cDeprecated
  • cDie
  • cError
  • checkLangInClients
  • checkPathInformation
  • cInclude
  • compareUrlStrings
  • conChangeTemplateForCat
  • conCopyArticle
  • conCopyArtLang
  • conCopyContainerConf
  • conCopyContent
  • conCopyMetaTags
  • conCopyTemplateConfiguration
  • conCreateLocationString
  • conDeeperCategoriesArray
  • conDeleteart
  • conEditArt
  • conEditFirstTime
  • conFetchCategoryTree
  • conFlagOnOffline
  • conGenerateCode
  • conGenerateCodeForAllArts
  • conGenerateCodeForAllArtsInCategory
  • conGenerateCodeForAllartsUsingLayout
  • conGenerateCodeForAllartsUsingMod
  • conGenerateCodeForAllArtsUsingTemplate
  • conGenerateCodeForArtInAllCategories
  • conGenerateCodeForClient
  • conGenerateKeywords
  • conGetAvailableMetaTagTypes
  • conGetCategoryArticleId
  • conGetCategoryAssignments
  • conGetContainerConfiguration
  • conGetContentFromArticle
  • conGetHtmlTranslationTable
  • conGetMetaValue
  • conGetTemplateConfigurationIdForArticle
  • conGetTemplateConfigurationIdForCategory
  • conGetTopmostCat
  • conGetUsedModules
  • conHtmlentities
  • conHtmlEntityDecode
  • conHtmlSpecialChars
  • conIsLocked
  • conLock
  • conLockBulkEditing
  • conMakeArticleIndex
  • conMakeCatOnline
  • conMakeInlineScript
  • conMakeOnline
  • conMakeOnlineBulkEditing
  • conMakePublic
  • conMakeStart
  • conMoveArticles
  • conPhp54Check
  • conRemoveOldCategoryArticle
  • conSaveContentEntry
  • conSetCodeFlag
  • conSetCodeFlagBulkEditing
  • conSetMetaValue
  • conSyncArticle
  • copyRightsForElement
  • createBulkEditingFunction
  • createRandomName
  • createRightsForElement
  • cWarning
  • dbGetColumns
  • dbGetIndexes
  • dbGetPrimaryKeyName
  • dbTableExists
  • dbUpgradeTable
  • defineIfNotDefined
  • deleteArtspec
  • deleteRightsForElement
  • deleteSystemProperty
  • displayDatetime
  • emptyLogFile
  • endAndLogTiming
  • extractNumber
  • generateDisplayFilePath
  • generateJs
  • getAllClientsAndLanguages
  • getArtLang
  • getArtspec
  • getAvailableContentTypes
  • getCanonicalDay
  • getCanonicalMonth
  • getDirectorySize
  • getEffectiveSetting
  • getEffectiveSettingsByType
  • getEncodingByLanguage
  • getFileContents
  • getFileInformation
  • getFileType
  • getGroupOrUserName
  • getIDForArea
  • getJsHelpContext
  • getLanguageNamesByClient
  • getLanguagesByClient
  • getmicrotime
  • getNamedFrame
  • getParam
  • getParentAreaId
  • getSearchResults
  • getStrExpandCollapseButton
  • getSystemProperties
  • getSystemPropertiesByType
  • getSystemProperty
  • getTemplateSelect
  • getUplExpandCollapseButton
  • htmldecode
  • htmlentities_iso88592
  • humanReadableSize
  • includePlugins
  • insertEmptyStrRow
  • ipMatch
  • isAlphanumeric
  • isArchive
  • isArtInMultipleUse
  • isFunctionDisabled
  • isGroup
  • isIPv4
  • isRunningFromWeb
  • isStartArticle
  • isUtf8
  • isValidMail
  • langActivateDeactivateLanguage
  • langDeleteLanguage
  • langEditLanguage
  • langGetTextDirection
  • langNewLanguage
  • langRenameLanguage
  • layDeleteLayout
  • layEditLayout
  • machineReadableSize
  • mailLogBulkEditingFunctions
  • mailLogDecodeAddresses
  • markSubMenuItem
  • mask
  • modDeleteModule
  • modEditModule
  • phpInfoToHtml
  • plugin_include
  • prCreateURLNameLocationString
  • prDeleteCacheFileContent
  • prGetCacheFileContent
  • prResolvePathViaCategoryNames
  • prResolvePathViaURLNames
  • prWriteCacheFileContent
  • putFileContents
  • recursiveCopy
  • removeFileInformation
  • renderBackendBreadcrumb
  • renderLabel
  • renderSelectProperty
  • renderTextProperty
  • saveGroupRights
  • saveRights
  • scanDirectory
  • scanPlugins
  • sendEncodingHeader
  • set_magic_quotes_gpc
  • setArtspecDefault
  • setArtspecOnline
  • setSystemProperty
  • showTree
  • startTiming
  • statCreateLocationString
  • statDisplayTopChooser
  • statDisplayYearlyTopChooser
  • statGetAvailableMonths
  • statGetAvailableYears
  • statResetStatistic
  • statsArchive
  • statsDisplayInfo
  • statsOverviewAll
  • statsOverviewTop
  • statsOverviewTopYear
  • statsOverviewYear
  • strAssignTemplate
  • strBuildSqlValues
  • strCheckTreeForErrors
  • strCopyCategory
  • strCopyTree
  • strDeeperCategoriesArray
  • strDeleteCategory
  • strHasArticles
  • strHasStartArticle
  • strMakePublic
  • strMakeVisible
  • strMoveCatTargetallowed
  • strMoveDownCategory
  • strMoveSubtree
  • strMoveUpCategory
  • strNewCategory
  • strNewTree
  • strNextBackwards
  • strNextDeeper
  • strNextDeeperAll
  • strNextPost
  • strOrderedPostTreeList
  • strRemakeTreeTable
  • strRenameCategory
  • strRenameCategoryAlias
  • strSortPrePost
  • strSyncCategory
  • systemHavePerm
  • tplAutoFillModules
  • tplBrowseLayoutForContainers
  • tplcfgDuplicate
  • tplDeleteTemplate
  • tplDuplicateTemplate
  • tplEditTemplate
  • tplGetContainerDefault
  • tplGetContainerMode
  • tplGetContainerName
  • tplGetContainerNumbersInLayout
  • tplGetContainerTypes
  • tplGetInUsedData
  • tplIsTemplateInUse
  • tplPreparseLayout
  • tplProcessSendContainerConfiguration
  • updateClientCache
  • updateFileInformation
  • uplCreateFriendlyName
  • uplDirectoryListRecursive
  • uplGetDirectoriesToExclude
  • uplGetFileExtension
  • uplGetFileIcon
  • uplGetFileTypeDescription
  • uplGetThumbnail
  • uplHasFiles
  • uplHasSubdirs
  • uplmkdir
  • uplRecursiveDBDirectoryList
  • uplRecursiveDirectoryList
  • uplRenameDirectory
  • uplSearch
  • uplSyncDirectory
  • uplSyncDirectoryDBFS
  • Overview
  • Package
  • Class
  • Tree
  • Deprecated
  • Todo
  1: <?php
  2: /**
  3:  * This file contains the system integrity backend page.
  4:  *
  5:  * @package          Core
  6:  * @subpackage       Backend
  7:  * @author           Thomas Stauer
  8:  * @copyright        four for business AG <www.4fb.de>
  9:  * @license          http://www.contenido.org/license/LIZENZ.txt
 10:  * @link             http://www.4fb.de
 11:  * @link             http://www.contenido.org
 12:  */
 13: 
 14: defined('CON_FRAMEWORK') || die('Illegal call: Missing framework initialization - request aborted.');
 15: 
 16: /**
 17:  *
 18:  * @package    Core
 19:  * @subpackage Backend
 20:  */
 21: class cTinymce4Configuration {
 22: 
 23:     /**
 24:      *
 25:      * @var bool
 26:      */
 27:     public $successfully = false;
 28: 
 29:     /**
 30:      *
 31:      * @var bool
 32:      */
 33:     private $_perm = false;
 34: 
 35:     /**
 36:      *
 37:      * @var array
 38:      */
 39:     private $_configErrors = array();
 40: 
 41:     /**
 42:      * Constructor function.
 43:      * Inits permission.
 44:      */
 45:     public function __construct() {
 46:         // decide whether user is allowed to change values
 47:         $this->_perm = ('sysadmin' === cRegistry::getAuth()->getPerms());
 48:     }
 49: 
 50:     /**
 51:      * Generate a div containing a label and a textbox.
 52:      *
 53:      * @param string $description
 54:      *        Label text before the textbox
 55:      * @param string $name
 56:      *        Name of textbox form element
 57:      * @param string $value
 58:      *        Default value of textbox
 59:      * @param number $width
 60:      *        Width of label in px
 61:      * @return cHTMLDiv
 62:      *        The div element containing label and textbox
 63:      */
 64:     private function _addLabelWithTextarea($description, $name, $value = '', $width = 75) {
 65:         $label = new cHTMLLabel($description, $name);
 66:         $label->setClass("sys_config_txt_lbl");
 67:         $label->setStyle('width:' . $width . 'px; vertical-align: top;');
 68: 
 69:         $textarea = new cHTMLTextarea($name);
 70:         $textarea->setValue($value);
 71:         $textarea->setAttribute('style', 'box-sizing: border-box; width: 600px;');
 72:         if (false === $this->_perm) {
 73:             $textarea->updateAttribute('disabled', 'disabled');
 74:         }
 75:         $div = new cHTMLDiv($label .  $textarea, 'systemSetting');
 76: 
 77:         return $div;
 78:     }
 79: 
 80:     /**
 81:      * Generates a cHTMLCheckbox based on function arguments and sets
 82:      * its disabled state based on permission check.
 83:      *
 84:      * @param string $description
 85:      *        Description that will be displayed in checkbox label
 86:      * @param string $name
 87:      *        Name of checkbox, this is important for fetching values
 88:      *        from sent form
 89:      * @param string $value
 90:      *        The value that will be sent as content in the name key
 91:      * @param bool $checked
 92:      *        Whether this checkbox is setup as checked
 93:      * @return cHTMLCheckbox
 94:      *        Checkbox with label
 95:      */
 96:     private function _addLabelWithCheckbox($description, $name, $value, $checked) {
 97:         $checkBox = new cHTMLCheckbox($name, $value, str_replace('[]', '_', $name . $value), (true === $checked));
 98:         $checkBox->setLabelText($description);
 99: 
100:         if (false === $this->_perm) {
101:             $checkBox->updateAttribute('disabled', 'disabled');
102:         }
103: 
104:         return $checkBox;
105:     }
106: 
107:     /**
108:      * Check if a type pattern matches value.
109:      *
110:      * @param string $type
111:      *        Pattern that is applied to value
112:      * @param string $value
113:      *        Value that is checked for pattern
114:      * @return boolean
115:      *        Whether type matches value
116:      */
117:     private function _checkType($type, $value) {
118:         if (true === empty($value)) {
119:             return true;
120:         }
121:         if (true === isset($value)) {
122:             // parameter is known, check it using type expression
123:             // preg match returns 1 if match occurs
124:             return (1 === preg_match($type, $value));
125:         }
126: 
127:         return false;
128:     }
129: 
130:     /**
131:      *
132:      * @param array haystack
133:      * @param array $needles
134:      * @return bool
135:      */
136:     private function _checkIsset(array $haystack, array $needles) {
137:         if (count($haystack) !== count($needles)) {
138:             return false;
139:         }
140:         foreach ($needles as $needle) {
141:             if (false === isset($haystack[$needle])) {
142:                 return false;
143:             }
144:         }
145: 
146:         return true;
147:     }
148: 
149:     /**
150:      * This function lists all external plugins that should be shown in
151:      * a table.
152:      *
153:      * @return string
154:      */
155:     private function _listExternalPlugins() {
156:         /// TODO: use a preference loading function for plugins to list
157:         $externalPlugins = static::get(array(), 'raw', 'externalplugins');
158: 
159:         // build a table
160:         $table = new cHTMLTable();
161:         $table->setClass('generic');
162: 
163:         // table row
164:         $headrow = new cHTMLTableRow();
165: 
166:         // table column 1 (plugin name)
167:         $col = new cHTMLTableHead();
168:         $col->appendContent(i18n('Name'));
169:         $headrow->appendContent($col);
170: 
171:         // table column 2 (plugin url)
172:         $col = new cHTMLTableHead();
173:         $col->appendContent(i18n('URL'));
174:         $headrow->appendContent($col);
175: 
176:         // table column 3 (user actions)
177:         $col = new cHTMLTableHead();
178:         $col->appendContent(i18n('Action'));
179:         $headrow->appendContent($col);
180: 
181:         // add columns to table
182:         $table->appendContent($headrow);
183: 
184:         // build table body
185:         $tbody = new cHTMLTableBody();
186:         $i = 0;
187:         $n = count($externalPlugins) -1;
188:         for ($i; $i < $n; $i++) {
189:             // new tr
190:             $row = new cHTMLTableRow();
191: 
192:             // create new td
193:             $td = new cHTMLTableData();
194:             $td->appendContent($externalPlugins[$i]['name']);
195: 
196:             // insert hidden input field
197:             $input = new cHTMLFormElement();
198:             $input->setAttribute('type', 'hidden');
199:             $input->setAttribute('name', 'externalplugins[' . $i . '][name]');
200:             $input->setAttribute('value', $externalPlugins[$i]['name']);
201:             $td->appendContent($input);
202: 
203:             // add td to tr
204:             $row->appendContent($td);
205: 
206:             // create new td
207:             $td = new cHTMLTableData();
208:             $td->appendContent($externalPlugins[$i]['url']);
209: 
210:             // insert hidden input field
211:             $input = new cHTMLFormElement();
212:             $input->setAttribute('type', 'hidden');
213:             $input->setAttribute('name', 'externalplugins[' . $i . '][url]');
214:             $input->setAttribute('value', $externalPlugins[$i]['url']);
215:             $td->appendContent($input);
216: 
217:             // add td to tr
218:             $row->appendContent($td);
219: 
220:             // create new td
221:             $td = new cHTMLTableData();
222:             if (true === $this->_perm) {
223:                 // Edit/delete links only for sysadmin
224:                 $oLinkDelete = new cHTMLLink();
225:                 $oLinkDelete->setCLink(cRegistry::getArea(), cRegistry::getFrame(), "system_wysiwyg_tinymce4_delete_item");
226:                 $oLinkDelete->setCustom("external_plugin_idx", urlencode($i));
227:                 $img = new cHTMLImage(cRegistry::getBackendUrl() . cRegistry::getConfigValue('path', 'images') . 'delete.gif');
228:                 $img->setAttribute('alt', i18n("Delete"));
229:                 $img->setAttribute('title', i18n("Delete"));
230:                 $oLinkDelete->appendContent($img);
231:                 $td->appendContent($oLinkDelete);
232:             }
233: 
234:             // add td to tr
235:             $row->appendContent($td);
236: 
237:             // insert row into table body
238:             $tbody->appendContent($row);
239:         }
240:         // append empty row to let user enter new plugins
241:         $row = new cHTMLTableRow();
242: 
243:         // create new td for plugin name
244:         $td = new cHTMLTableData();
245:         $input = new cHTMLFormElement('externalplugins[' . $i . '][name]');
246:         $td->appendContent($input);
247:         $row->appendContent($td);
248: 
249:         // create new td for plugin url
250:         $td = new cHTMLTableData();
251:         $input = new cHTMLFormElement('externalplugins[' . $i . '][url]');
252:         $td->appendContent($input);
253:         $row->appendContent($td);
254: 
255:         // empty action column
256:         $td = new cHTMLTableData();
257:         $row->appendContent($td);
258: 
259:         // append row to table body
260:         $tbody->appendContent($row);
261: 
262: 
263:         // insert table body into table
264:         $table->appendContent($tbody);
265: 
266:         // return table as string
267:         return $table->render();
268:     }
269: 
270:     /**
271:      * Function to check if toolbar data contains valid input.
272:      *
273:      * @param string $toolbarData
274:      *        The toolbar data to check for validity
275:      * @return boolean
276:      *        True if toolbar data is valid, false otherwise
277:      */
278:     private function _validateToolbarN($toolbarData) {
279:         // do not use cRequestValidator instance
280:         // because it does not support multi-dimensional arrays
281:         if (false === $this->_checkType('/^[a-zA-Z0-9 \-\|_]*$/', $toolbarData)
282:         || false !== strpos($toolbarData, '||')) {
283:             return false;
284:         }
285: 
286:         return true;
287:     }
288: 
289:     /**
290:      * Variadic function to obtain config values using nested key values.
291:      *
292:      * @param mixed $default
293:      *        Default value to use in case no value is set
294:      * param string keys
295:      *        The keys to access values in configuration
296:      * @return string|array
297:      */
298:     public static function get($default) {
299:         $cfg = cRegistry::getConfig();
300: 
301:         if (false === isset($cfg['wysiwyg'])
302:         || false === isset($cfg['wysiwyg']['tinymce4'])) {
303:             $configPath = cRegistry::getConfigValue('path', 'contenido_config') . 'config.wysiwyg_tinymce4.php';
304:             // check if configuration file exists
305:             if (true !== cFileHandler::exists($configPath)) {
306:                 return $default;
307:             }
308:             // check if file is reable
309:             if (true !== cFileHandler::readable($configPath)) {
310:                 return $default;
311:             }
312:             // Include configuration file
313:             require $configPath;
314:         }
315: 
316:         // check number of keys passed to function
317:         $numargs = func_num_args();
318:         if (0 === $numargs) {
319:             return $default;
320:         }
321: 
322:         // walk through config
323:         $result = cRegistry::getConfig();
324: 
325:         // select ['wysiwyg']['tinymce4'] by default
326:         if (false === isset($result['wysiwyg'])) {
327:             return $default;
328:         }
329:         if (false === $result['wysiwyg']['tinymce4']) {
330:             return $default;
331:         }
332:         $result = $result['wysiwyg']['tinymce4'];
333:         // get values in key path that user requested
334:         for ($i = 0; $i < $numargs -1; $i++) {
335:             if (false === isset($result[func_get_arg(1 + $i)])) {
336:                 return $default;
337:             }
338:             // jump one array level deeper into the result
339:             $result = $result[func_get_arg(1 + $i)];
340:         }
341: 
342:         return $result;
343:     }
344: 
345:     /**
346:      * Function to validate form from showConfigurationForm().
347:      *
348:      * @param array $config
349:      *        The post parameters of submitted form
350:      * @return boolean|array
351:      *        False if data should not be saved, otherwise data to save
352:      */
353:     public function validateForm($config) {
354:         // Checks for cross site requests and cross site scripting
355:         // are omitted due to time constraints
356: 
357:         // User must be system administrator to change the settings
358:         if ('sysadmin' !== cRegistry::getAuth()->getPerms()) {
359:             return false;
360:         }
361: 
362:         // remove not used area field
363:         unset($config['area']);
364:         // remove not used frame field
365:         unset($config['frame']);
366:         // remove not used contenido field
367:         unset($config['contenido']);
368: 
369:         // remove x and y values from image submit button in in form
370:         unset($config['submit_x']);
371:         unset($config['submit_y']);
372: 
373:         // form action (added in showConfigurationForm() inside this
374:         // class) is not used for saving config
375:         if ('system_wysiwyg_tinymce4_delete_item' === $_GET['action']) {
376:             return $this->removeExternalPluginLoad($_GET);
377:         }
378:         unset($config['action']);
379: 
380:         // check if config should be deleted
381:         if (isset($_POST['reset'])) {
382:             $noti = new cGuiNotification();
383: 
384:             // try to delete configuration
385:             $configPath = cRegistry::getConfigValue('path', 'contenido_config');
386:             $configPath .= 'config.wysiwyg_tinymce4.php';
387:             if (cFileHandler::exists($configPath)
388:             && cFileHandler::writeable($configPath)) {
389:                 cFileHandler::remove($configPath);
390:                 $noti->displayNotification(cGuiNotification::LEVEL_INFO, i18n('TinyMCE 4 configuration got reset back to default'));
391:             } else {
392:                 // can not delete config, display message
393:                 $noti->displayNotification(cGuiNotification::LEVEL_ERROR, i18n('Can not delete config file'));
394:             }
395: 
396:             // do not save config
397:             return false;
398:         }
399: 
400:         // check if all array entries actually exist
401:         // abort if too many values are encountered
402:         $shouldArrayStructure =  array (
403:             'tinymce4_full' =>
404:             array (
405:                     'toolbar1',
406:                     'toolbar2',
407:                     'toolbar3',
408:                     'plugins'
409:             ),
410:             'tinymce4_fullscreen' =>
411:             array (
412:                     'toolbar1',
413:                     'toolbar2',
414:                     'toolbar3',
415:                     'plugins'
416:             ),
417:             'contenido_lists',
418:             'contenido_gzip',
419:             'custom',
420:         );
421: 
422:         // get name of first key
423:         reset($config);
424:         $key = key($config);
425: 
426:         if (false === isset($_POST['externalplugins']) && false === $this->_checkIsset($config[$key]['tinymce4_full'], $shouldArrayStructure['tinymce4_full'])) {
427:             $this->_configErrors[] = i18n('Fullscreen config of inline editor is erroneous.');
428:             return false;
429:         }
430:         if (false === isset($_POST['externalplugins']) && false === $this->_checkIsset($config[$key]['tinymce4_fullscreen'], $shouldArrayStructure['tinymce4_fullscreen'])) {
431:             $this->_configErrors[] = i18n('Config of editor on separate editor page is erroneous.');
432:             return false;
433:         }
434:         if (false === isset($_POST['externalplugins']) && false === isset($config[$key]['custom'])) {
435:             $this->_configErrors[] = i18n('Custom configuration of tinyMCE 4 is not set.');
436:             return false;
437:         }
438: 
439:         // do not use cRequestValidator instance because it does not support multi-dimensional arrays
440:         if (false === $this->_validateToolbarN($config[$key]['tinymce4_full']['toolbar1'])
441:         || false === $this->_validateToolbarN($config[$key]['tinymce4_full']['toolbar2'])
442:         || false === $this->_validateToolbarN($config[$key]['tinymce4_full']['toolbar3'])
443:         || false === $this->_validateToolbarN($config[$key]['tinymce4_fullscreen']['toolbar1'])
444:         || false === $this->_validateToolbarN($config[$key]['tinymce4_fullscreen']['toolbar2'])
445:         || false === $this->_validateToolbarN($config[$key]['tinymce4_fullscreen']['toolbar3'])) {
446:             $this->_configErrors[] = i18n('Toolbar(s) of editor contain erroneous data.');
447:             return false;
448:         }
449: 
450:         // remove last entry of external plugins if it is empty
451:         $lastExternalPlugin = $config[$key]['externalplugins'][count($config[$key]['externalplugins']) -1];
452:         if ('' === $lastExternalPlugin['name']
453:         && '' === $lastExternalPlugin['url']) {
454:             unset($config[$key]['externalplugins'][count($config[$key]['externalplugins']) -1]);
455:         }
456: 
457:         // custom tinymce 4 settings overwrite other fields
458:         if (cRegistry::getConfigValue('simulate_magic_quotes') === true) {
459:             $config[$key]['custom'] = stripslashes($config[$key]['custom']);
460:         }
461: 
462:         // unescape strings then build config
463:         $customConfig = (array) json_decode($config[$key]['custom'], true);
464:         switch(json_last_error()) {
465:             case JSON_ERROR_DEPTH:
466:                 $this->_configErrors[] = i18n('Maximum stack depth exceeded while decoding json');
467:             return false;
468:             case JSON_ERROR_CTRL_CHAR:
469:                 $this->_configErrors[] = i18n('Unexpected control character found');
470:             return false;
471:             case JSON_ERROR_SYNTAX:
472:                 $this->_configErrors[] = i18n('Syntax error, malformed JSON');
473:             return false;
474:         }
475: 
476:         // append new config to old config
477:         $origConfig = static::get(array(), 'raw');
478:         $config['raw'] = array_merge($origConfig, $config);
479:         //$config['raw'] = $config;
480: 
481:         // use custom parameters if they are correct JSON
482:         if (JSON_ERROR_NONE === json_last_error()) {
483:             $config[$key] = array_merge($config[$key], $customConfig);
484:         }
485:         unset($config[$key]['custom']);
486: 
487:         // put all config values into ['tinymce4']['tinymce4']
488:         // put the raw settings of config page into ['tinymce4']['raw']
489:         $origConfig = static::get(array(), 'tinymce4');
490:         $config = array_merge($origConfig, $config);
491:         $res = array('tinymce4' => array('tinymce4' =>$config));
492:         //unset($res['tinymce4']['tinymce4']['custom']);
493:         $res['tinymce4']['raw'] = $res['tinymce4']['tinymce4']['raw'];
494:         unset($res['tinymce4']['tinymce4']['raw']);
495: 
496:         // $config contains only valid content, returned processed config
497:         return $res;
498:     }
499: 
500:     /**
501:      * Do not load external plugin if user has permission to request that.
502:      *
503:      * @param array $form
504:      *        get parameters from deletion link
505:      * @return boolean|array
506:      *        False if data should not be saved, otherwise data to save
507:      */
508:     public function removeExternalPluginLoad($form) {
509:         // abort if user has not sufficient permissions
510:         if (false === $this->_perm) {
511:             return;
512:         }
513: 
514:         $pluginToRemoveIdx = (int) $form['external_plugin_idx'];
515: 
516:         // load config through usage of get function
517:         $settings = static::get(false);
518: 
519:         // no config or no external plugins or no plugin with that index
520:         // means nothing to remove
521:         if (false === $settings
522:         || false === isset($settings['raw'])
523:         || false === isset($settings['raw']['externalplugins'])
524:         || false === isset($settings['raw']['externalplugins'][$pluginToRemoveIdx])) {
525:             return false;
526:         }
527: 
528:         // remove value from raw settings
529:         unset($settings['raw']['externalplugins'][$pluginToRemoveIdx]);
530:         // remove stray custom setting
531:         unset($settings['raw']['externalplugins']['custom']);
532: 
533:         // re-index array
534:         $settings['raw']['externalplugins'] = array_values($settings['raw']['externalplugins']);
535: 
536:         // apply raw settings to computed settings
537:         $settings['tinymce4']['externalplugins'] = $settings['raw']['externalplugins'];
538: 
539:         return array('tinymce4' => $settings);
540:     }
541: 
542:     /**
543:      * Generates an HTML form to configure tinymce 4.
544:      */
545:     public function showConfigurationForm() {
546:         $page = new cGuiPage('system_wysiwyg_tinymce4', '', '5');
547:         $auth = cRegistry::getAuth();
548:         $frame = cRegistry::getFrame();
549:         $area = cRegistry::getArea();
550: 
551:         // validate if user has permission to edit this area
552:         if (false === cRegistry::getPerm()->have_perm_area_action($area, 'edit_system_wysiwyg_tinymce4')) {
553:             $page->displayCriticalError(i18n('Access denied'));
554:             $page->render();
555:             return;
556:         }
557: 
558:         if (count($this->_configErrors) > 0) {
559:             $errorMessage = i18n('The following errors occurred when trying to verify configuration:') . '<ul>';
560:             foreach ($this->_configErrors as $error) {
561:                 $errorMessage .= '<li>' . $error . '</li>';
562:             }
563:             $errorMessage .= '</ul>';
564:             $page->displayError($errorMessage);
565:         }
566: 
567:         if ($this->successfully === true) $page->displayOk(i18n("Changes saved successfully!"));
568: 
569:         $page->displayInfo(sprintf(i18n('Currently active WYSIWYG editor: %s'), cWYSIWYGEditor::getCurrentWysiwygEditorName()));
570: 
571:         $oTypeColl = new cApiTypeCollection();
572:         $oTypeColl->select();
573:         $result = '';
574:         while (false !== ($typeEntry = $oTypeColl->next())) {
575:             // specify a shortcut for type field
576:             $curType = $typeEntry->get('type');
577: 
578:             $contentTypeClassName = cTypeGenerator::getContentTypeClassName($curType);
579:             if (false === class_exists($contentTypeClassName)) {
580:                 continue;
581:             }
582:             $cContentType = new $contentTypeClassName(null, 0, array());
583:             if (false === $cContentType->isWysiwygCompatible()) {
584:                 continue;
585:             }
586: 
587: 
588:             $form = new cGuiTableForm('system_wysiwyg_tinymce4_' . strtolower($curType));
589:             $form->setAcceptCharset('UTF-8');
590: 
591:             $form->addHeader(i18n('TinyMCE 4 configuration for ') . $curType);
592: 
593:             $form->setVar('area', $area);
594:             $form->setVar('frame', $frame);
595:             $form->setVar('action', 'edit_tinymce4');
596: 
597: 
598:             $containerDiv = new cHTMLDiv();
599:             if ('CMS_HTMLHEAD' === $curType) {
600:                 $defaultToolbar1 = static::get('undo redo | consave conclose', 'raw', $curType, 'tinymce4_full', 'toolbar1');
601:                 $defaultToolbar2 = static::get('', 'raw', $curType, 'tinymce4_full', 'toolbar2');
602:                 $defaultToolbar3 = static::get('', 'raw', $curType, 'tinymce4_full', 'toolbar3');
603:                 $defaultPlugins = static::get('conclose', 'raw', $curType, 'tinymce4_full', 'plugins');
604:             } else {
605:                 $defaultToolbar1 = static::get('cut copy paste pastetext | searchreplace | undo redo | bold italic underline strikethrough subscript superscript | insertdatetime preview | visualchars nonbreaking template pagebreak | help | fullscreen', 'raw', $curType, 'tinymce4_full', 'toolbar1');
606:                 $defaultToolbar2 = static::get('link unlink anchor image media hr | bullist numlist | outdent indent blockquote | alignleft aligncenter alignright alignfull removeformat | forecolor backcolor | ltr rtl | charmap | code', 'raw', $curType, 'tinymce4_full', 'toolbar2');
607:                 $defaultToolbar3 = static::get('table | formatselect fontselect fontsizeselect | consave conclose', 'raw', $curType, 'tinymce4_full', 'toolbar3');
608:                 $defaultPlugins = static::get('charmap code table conclose hr image link pagebreak layer insertdatetime preview anchor media searchreplace print contextmenu paste directionality fullscreen visualchars nonbreaking template textcolor', 'raw', $curType, 'tinymce4_full', 'plugins');
609:             }
610:             $containerDiv->appendContent($this->_addLabelWithTextarea('Toolbar 1:', $curType . '[tinymce4_full][toolbar1]', $defaultToolbar1));
611:             $containerDiv->appendContent($this->_addLabelWithTextarea('Toolbar 2:', $curType . '[tinymce4_full][toolbar2]', $defaultToolbar2));
612:             $containerDiv->appendContent($this->_addLabelWithTextarea('Toolbar 3:', $curType . '[tinymce4_full][toolbar3]', $defaultToolbar3));
613:             $containerDiv->appendContent($this->_addLabelWithTextarea('Plugins:', $curType . '[tinymce4_full][plugins]', $defaultPlugins));
614:             $form->add(i18n('Settings of editor in separate editor page'), $containerDiv->render());
615: 
616:             $containerDiv = new cHTMLDiv();
617:             if ('CMS_HTMLHEAD' === $curType) {
618:                 $defaultToolbar1 = static::get('undo redo | consave conclose', 'raw', $curType, 'tinymce4_inline', 'toolbar1');
619:                 $defaultToolbar2 = static::get('', 'raw', $curType, 'tinymce4_inline', 'toolbar2');
620:                 $defaultToolbar3 = static::get('', 'raw', $curType, 'tinymce4_inline', 'toolbar3');
621:                 $defaultPlugins = static::get('conclose', 'raw', $curType, 'tinymce4_inline', 'plugins');
622:             } else {
623:                 $defaultToolbar1 = static::get('bold italic underline strikethrough | undo redo | bullist numlist separator forecolor backcolor | alignleft aligncenter alignright | confullscreen | consave conclose', 'raw', $curType, 'tinymce4_inline', 'toolbar1');
624:                 $defaultToolbar2 = static::get('', 'raw', $curType, 'tinymce4_inline', 'toolbar2');
625:                 $defaultToolbar3 = static::get('', 'raw', $curType, 'tinymce4_inline', 'toolbar3');
626:                 $defaultPlugins = static::get('conclose confullscreen media table textcolor', 'raw', $curType, 'tinymce4_inline', 'plugins');
627:             }
628:             $containerDiv->appendContent($this->_addLabelWithTextarea('Toolbar 1:', $curType . '[tinymce4_inline][toolbar1]', $defaultToolbar1));
629:             $containerDiv->appendContent($this->_addLabelWithTextarea('Toolbar 2:', $curType . '[tinymce4_inline][toolbar2]', $defaultToolbar2));
630:             $containerDiv->appendContent($this->_addLabelWithTextarea('Toolbar 3:', $curType . '[tinymce4_inline][toolbar3]', $defaultToolbar3));
631:             $containerDiv->appendContent($this->_addLabelWithTextarea('Plugins:', $curType . '[tinymce4_inline][plugins]', $defaultPlugins));
632:             $form->add(i18n('Settings of inline editor in inline mode'), $containerDiv->render());
633: 
634:             $containerDiv = new cHTMLDiv();
635:             if ('CMS_HTMLHEAD' === $curType) {
636:                 $defaultToolbar1 = static::get('undo redo | consave conclose', 'raw', $curType, 'tinymce4_fullscreen', 'toolbar1');
637:                 $defaultToolbar2 = static::get('', 'raw', $curType, 'tinymce4_fullscreen', 'toolbar2');
638:                 $defaultToolbar3 = static::get('', 'raw', $curType, 'tinymce4_fullscreen', 'toolbar3');
639:                 $defaultPlugins = static::get('conclose', 'raw', $curType, 'tinymce4_fullscreen', 'plugins');
640:             } else {
641:                 $defaultToolbar1 = static::get('cut copy paste pastetext | searchreplace | undo redo | bold italic underline strikethrough subscript superscript | insertdatetime preview | visualchars nonbreaking template pagebreak | help | fullscreen', 'raw', $curType, 'tinymce4_fullscreen', 'toolbar1');
642:                 $defaultToolbar2 = static::get('link unlink anchor image media | bullist numlist | outdent indent blockquote | alignleft aligncenter alignright alignfull removeformat | forecolor backcolor | ltr rtl | charmap | code', 'raw', $curType, 'tinymce4_fullscreen', 'toolbar2');
643:                 $defaultToolbar3 = static::get('table | formatselect fontselect fontsizeselect | consave conclose', 'raw', $curType, 'tinymce4_fullscreen', 'toolbar3');
644:                 $defaultPlugins = static::get('charmap code conclose table hr image link pagebreak layer insertdatetime preview anchor media searchreplace print contextmenu paste directionality fullscreen visualchars nonbreaking template textcolor', 'raw', $curType, 'tinymce4_fullscreen', 'plugins');
645:             }
646:             $containerDiv->appendContent($this->_addLabelWithTextarea('Toolbar 1:', $curType . '[tinymce4_fullscreen][toolbar1]', $defaultToolbar1));
647:             $containerDiv->appendContent($this->_addLabelWithTextarea('Toolbar 2:', $curType . '[tinymce4_fullscreen][toolbar2]', $defaultToolbar2));
648:             $containerDiv->appendContent($this->_addLabelWithTextarea('Toolbar 3:', $curType . '[tinymce4_fullscreen][toolbar3]', $defaultToolbar3));
649:             $containerDiv->appendContent($this->_addLabelWithTextarea('Plugins:', $curType . '[tinymce4_fullscreen][plugins]', $defaultPlugins));
650:             $form->add(i18n('Settings of inline editor in fullscreen mode'), $containerDiv->render());
651: 
652:             // GZIP editor over HTTP using tinymce's library
653:             $containerDiv = new cHTMLDiv();
654:             $checked = 'contenido_gzip' === static::get(false, 'raw', $curType, 'contenido_gzip');
655:             $containerDiv->appendContent($this->_addLabelWithCheckbox(i18n('GZIP TinyMCE (only activate if server does not compress content already)'), $curType . '[contenido_gzip]', 'contenido_gzip', $checked));
656:             $form->add(i18n('contenido_gzip'), $containerDiv->render());
657: 
658:             // Add jump lists to tinymce's dialogs
659:             $containerDiv = new cHTMLDiv();
660:             $checked = true === ('image' === static::get(false, 'raw', $curType, 'contenido_lists', 'image'));
661:             $containerDiv->appendContent($this->_addLabelWithCheckbox(i18n('Provide jump lists in image insertion dialog'), $curType . '[contenido_lists][image]', 'image', $checked));
662:             $checked = true === ('link' === static::get(false, 'raw', $curType, 'contenido_lists', 'link'));
663:             $containerDiv->appendContent($this->_addLabelWithCheckbox(i18n('Provide jump lists in link insertion dialog'), $curType . '[contenido_lists][link]', 'link', $checked));
664:             $form->add(i18n('contenido_lists'), $containerDiv->render());
665: 
666:             //add textarea for custom tinymce 4 settings
667:             $textarea = new cHTMLTextarea($curType . '[custom]');
668:             $textarea->setAttribute('style', 'width: 99%;');
669:             $defaultParams = '';
670:             if ('CMS_HTMLHEAD' === $curType) {
671:                 $defaultParams = '{' . PHP_EOL . '"inline": true,' . PHP_EOL . '"menubar": false' . PHP_EOL . '}';
672:             }
673:             $textarea->setValue(static::get($defaultParams, 'raw', $curType, 'custom'));
674:             $form->add(i18n('Additional parameters (JSON passed to tinymce constructor)'), $textarea->render());
675: 
676:             // check permission to save system wysiwyg editor settings
677:             if (false === $this->_perm) {
678:                 $form->setActionButton('submit', cRegistry::getBackendUrl() . 'images/but_ok_off.gif', i18n("You are not sysadmin. You can't change these settings."), 's');
679:             }
680:             $result .= '<p>' . $form->render() . '</p>';
681:         }
682: 
683:         // external plugins (can not be configured per CMS-type)
684:         $form = new cGuiTableForm('system_wysiwyg_tinymce4_external_plugins');
685:         $form->setAcceptCharset('UTF-8');
686:         $form->addHeader(i18n('TinyMCE 4 configuration for external plugins'));
687: 
688:         $form->setVar('area', $area);
689:         $form->setVar('frame', $frame);
690:         $form->setVar('action', 'edit_tinymce4');
691:         $containerDiv = new cHTMLDiv();
692:         $containerDiv->appendContent($this->_listExternalPlugins());
693:         $form->add(i18n('External plugins to load'), $containerDiv);
694:         $result .= '<p>' . $form->render() . '</p>';
695: 
696:         $configPath = cRegistry::getConfigValue('path', 'contenido_config');
697:         $configPath .= 'config.wysiwyg_tinymce4.php';
698:         if (cFileHandler::exists($configPath)
699:         && cFileHandler::writeable($configPath)) {
700:             $resetForm = new cHTMLForm('system_wysiwyg_tinymce4_general_options', 'main.php', 'post');
701:             $resetForm->setVar('area', $area);
702:             $resetForm->setVar('frame', $frame);
703:             $resetForm->setVar('action', 'edit_tinymce4');
704:             $oResetButton = new cHTMLButton('reset', i18n('Reset configuration back to default'));
705:             $oResetButton->setAttribute('value', i18n('Reset Configuration'));
706: 
707:             $resetForm = $resetForm->appendContent($oResetButton);
708:             $result .= $resetForm->render();
709:         }
710: 
711: 
712:         $page->set('s', 'FORM', $result);
713:         $page->set('s', 'RELOAD_HEADER', (false) ? 'true' : 'false');
714:         $page->render();
715:     }
716: }
717: 
CMS CONTENIDO 4.9.11 API documentation generated by ApiGen 2.8.0