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:  * @version          SVN Revision $Rev:$
  8:  *
  9:  * @author           Thomas Stauer
 10:  * @copyright        four for business AG <www.4fb.de>
 11:  * @license          http://www.contenido.org/license/LIZENZ.txt
 12:  * @link             http://www.4fb.de
 13:  * @link             http://www.contenido.org
 14:  */
 15: 
 16: defined('CON_FRAMEWORK') || die('Illegal call: Missing framework initialization - request aborted.');
 17: 
 18: class cTinymce4Configuration {
 19:     private $_perm = false;
 20:     private $_configErrors = array();
 21: 
 22:     /**
 23:      * Constructor function
 24:      * Inits permission
 25:      */
 26:     public function __construct() {
 27:         // decide whether user is allowed to change values
 28:         $this->_perm = ('sysadmin' === cRegistry::getAuth()->getPerms());
 29:     }
 30: 
 31:     /**
 32:      * Generate a div containing a label and a textbox
 33:      * @param string $description Label text before the textbox
 34:      * @param string $name Name of textbox form element
 35:      * @param string $value Default value of textbox
 36:      * @param number $width Width of label in px
 37:      * @return cHTMLDiv The div element containing label and textbox
 38:      */
 39:     private function _addLabelWithTextarea($description, $name, $value = '', $width = 75) {
 40:         $label = new cHTMLLabel($description, $name);
 41:         $label->setClass("sys_config_txt_lbl");
 42:         $label->setStyle('width:' . $width . 'px; vertical-align: top;');
 43: 
 44:         $textarea = new cHTMLTextarea($name);
 45:         $textarea->setValue($value);
 46:         $textarea->setAttribute('style', 'box-sizing: border-box; width: 600px;');
 47:         if (false === $this->_perm) {
 48:             $textarea->updateAttribute('disabled', 'disabled');
 49:         }
 50:         $div = new cHTMLDiv($label .  $textarea, 'systemSetting');
 51: 
 52:         return $div;
 53:     }
 54: 
 55:     /**
 56:      * Generates a cHTMLCheckbox based on function arguments and sets its disabled state based on permission check
 57:      * @param string $description Description that will be displayed in checkbox label
 58:      * @param string $name Name of checkbox, this is important for fetching values from sent form
 59:      * @param string $value The value that will be sent as content in the name key
 60:      * @param bool $checked Whether this checkbox is setup as checked
 61:      * @return cHTMLCheckbox Checkbox with label
 62:      */
 63:     private function _addLabelWithCheckbox($description, $name, $value, $checked) {
 64:         $checkBox = new cHTMLCheckbox($name, $value, str_replace('[]', '_', $name . $value), (true === $checked));
 65:         $checkBox->setLabelText($description);
 66: 
 67:         if (false === $this->_perm) {
 68:             $checkBox->updateAttribute('disabled', 'disabled');
 69:         }
 70: 
 71:         return $checkBox;
 72:     }
 73: 
 74:     /**
 75:      * Check if a type pattern matches value
 76:      * @param string $type Pattern that is applied to value
 77:      * @param string $value Value that is checked for pattern
 78:      * @return boolean Whether type matches value
 79:      */
 80:     private function _checkType($type, $value) {
 81:         if (true === empty($value)) {
 82:             return true;
 83:         }
 84:         if (true === isset($value)) {
 85:             // parameter is known, check it using type expression
 86:             // preg match returns 1 if match occurs
 87:             return (1 === preg_match($type, $value));
 88:         }
 89: 
 90:         return false;
 91:     }
 92: 
 93:     private function _checkIsset(array $haystack, array $needles) {
 94:         if (count($haystack) !== count($needles)) {
 95:             return false;
 96:         }
 97:         foreach ($needles as $needle) {
 98:             if (false === isset($haystack[$needle])) {
 99:                 return false;
100:             }
101:         }
102: 
103:         return true;
104:     }
105: 
106:     /**
107:      * This function lists all external plugins that should be shown in a table
108:      * @return string
109:      */
110:     private function _listExternalPlugins() {
111:         /// TODO: use a preference loading function for plugins to list
112:         $externalPlugins = static::get(array(), 'raw', 'externalplugins');
113: 
114:         // build a table
115:         $table = new cHTMLTable();
116:         $table->setClass('generic');
117: 
118:         // table row
119:         $headrow = new cHTMLTableRow();
120: 
121:         // table column 1 (plugin name)
122:         $col = new cHTMLTableHead();
123:         $col->appendContent(i18n('Name'));
124:         $headrow->appendContent($col);
125: 
126:         // table column 2 (plugin url)
127:         $col = new cHTMLTableHead();
128:         $col->appendContent(i18n('URL'));
129:         $headrow->appendContent($col);
130: 
131:         // table column 3 (user actions)
132:         $col = new cHTMLTableHead();
133:         $col->appendContent(i18n('Action'));
134:         $headrow->appendContent($col);
135: 
136:         // add columns to table
137:         $table->appendContent($headrow);
138: 
139:         // build table body
140:         $tbody = new cHTMLTableBody();
141:         $i = 0;
142:         $n = count($externalPlugins) -1;
143:         for ($i; $i < $n; $i++) {
144:             // new tr
145:             $row = new cHTMLTableRow();
146: 
147:             // create new td
148:             $td = new cHTMLTableData();
149:             $td->appendContent($externalPlugins[$i]['name']);
150: 
151:             // insert hidden input field
152:             $input = new cHTMLFormElement();
153:             $input->setAttribute('type', 'hidden');
154:             $input->setAttribute('name', 'externalplugins[' . $i . '][name]');
155:             $input->setAttribute('value', $externalPlugins[$i]['name']);
156:             $td->appendContent($input);
157: 
158:             // add td to tr
159:             $row->appendContent($td);
160: 
161:             // create new td
162:             $td = new cHTMLTableData();
163:             $td->appendContent($externalPlugins[$i]['url']);
164: 
165:             // insert hidden input field
166:             $input = new cHTMLFormElement();
167:             $input->setAttribute('type', 'hidden');
168:             $input->setAttribute('name', 'externalplugins[' . $i . '][url]');
169:             $input->setAttribute('value', $externalPlugins[$i]['url']);
170:             $td->appendContent($input);
171: 
172:             // add td to tr
173:             $row->appendContent($td);
174: 
175:             // create new td
176:             $td = new cHTMLTableData();
177:             if (true === $this->_perm) {
178:                 // Edit/delete links only for sysadmin
179:                 $oLinkDelete = new cHTMLLink();
180:                 $oLinkDelete->setCLink(cRegistry::getArea(), cRegistry::getFrame(), "system_wysiwyg_tinymce4_delete_item");
181:                 $oLinkDelete->setCustom("external_plugin_idx", urlencode($i));
182:                 $img = new cHTMLImage(cRegistry::getBackendUrl() . cRegistry::getConfigValue('path', 'images') . 'delete.gif');
183:                 $img->setAttribute('alt', i18n("Delete"));
184:                 $img->setAttribute('title', i18n("Delete"));
185:                 $oLinkDelete->appendContent($img);
186:                 $td->appendContent($oLinkDelete);
187:             }
188: 
189:             // add td to tr
190:             $row->appendContent($td);
191: 
192:             // insert row into table body
193:             $tbody->appendContent($row);
194:         }
195:         // append empty row to let user enter new plugins
196:         $row = new cHTMLTableRow();
197: 
198:         // create new td for plugin name
199:         $td = new cHTMLTableData();
200:         $input = new cHTMLFormElement('externalplugins[' . $i . '][name]');
201:         $td->appendContent($input);
202:         $row->appendContent($td);
203: 
204:         // create new td for plugin url
205:         $td = new cHTMLTableData();
206:         $input = new cHTMLFormElement('externalplugins[' . $i . '][url]');
207:         $td->appendContent($input);
208:         $row->appendContent($td);
209: 
210:         // empty action column
211:         $td = new cHTMLTableData();
212:         $row->appendContent($td);
213: 
214:         // append row to table body
215:         $tbody->appendContent($row);
216: 
217: 
218:         // insert table body into table
219:         $table->appendContent($tbody);
220: 
221:         // return table as string
222:         return $table->render();
223:     }
224: 
225:     /**
226:      * Function to check if toolbar data contains valid input
227:      * @param string $toolbarData The toolbar data to check for validity
228:      * @return boolean True if toolbar data is valid, false otherwise
229:      */
230:     private function _validateToolbarN($toolbarData) {
231:         // do not use cRequestValidator instance because it does not support multi-dimensional arrays
232:         if (false === $this->_checkType('/^[a-zA-Z0-9 \-\|_]*$/', $toolbarData)
233:         || false !== strpos($toolbarData, '||')) {
234:             return false;
235:         }
236: 
237:         return true;
238:     }
239: 
240:     /**
241:      * Variadic function to obtain config values using nested key values
242:      * @param mixed $default Default value to use in case no value is set
243:      * @param string keys The keys to access values in configuration
244:      */
245:     public static function get($default) {
246:         $cfg = cRegistry::getConfig();
247: 
248:         if (false === isset($cfg['wysiwyg'])
249:         || false === isset($cfg['wysiwyg']['tinymce4'])) {
250:             $configPath = cRegistry::getConfigValue('path', 'contenido_config') . 'config.wysiwyg_tinymce4.php';
251:             // check if configuration file exists
252:             if (true !== cFileHandler::exists($configPath)) {
253:                 return $default;
254:             }
255:             // check if file is reable
256:             if (true !== cFileHandler::readable($configPath)) {
257:                 return $default;
258:             }
259:             // Include configuration file
260:             require $configPath;
261:         }
262: 
263:         // check number of keys passed to function
264:         $numargs = func_num_args();
265:         if (0 === $numargs) {
266:             return $default;
267:         }
268: 
269:         // walk through config
270:         $result = cRegistry::getConfig();
271: 
272:         // select ['wysiwyg']['tinymce4'] by default
273:         if (false === isset($result['wysiwyg'])) {
274:             return $default;
275:         }
276:         if (false === $result['wysiwyg']['tinymce4']) {
277:             return $default;
278:         }
279:         $result = $result['wysiwyg']['tinymce4'];
280:         // get values in key path that user requested
281:         for ($i = 0; $i < $numargs -1; $i++) {
282:             if (false === isset($result[func_get_arg(1 + $i)])) {
283:                 return $default;
284:             }
285:             // jump one array level deeper into the result
286:             $result = $result[func_get_arg(1 + $i)];
287:         }
288: 
289:         return $result;
290:     }
291: 
292:     /**
293:      * Function to validate form from showConfigurationForm()
294:      * @param array $config The post parameters of submitted form
295:      * @return boolean|array False if data should not be saved, otherwise data to save
296:      */
297:     public function validateForm($config) {
298:         // Checks for cross site requests and cross site scripting are omitted due to time constraints
299: 
300:         // User must be system administrator to change the settings
301:         if ('sysadmin' !== cRegistry::getAuth()->getPerms()) {
302:             return false;
303:         }
304: 
305:         // remove not used area field
306:         unset($config['area']);
307:         // remove not used frame field
308:         unset($config['frame']);
309:         // remove not used contenido field
310:         unset($config['contenido']);
311: 
312:         // remove x and y values from image submit button in in form
313:         unset($config['submit_x']);
314:         unset($config['submit_y']);
315: 
316:         // form action (added in showConfigurationForm() inside this class) is not used for saving config
317:         if ('system_wysiwyg_tinymce4_delete_item' === $_GET['action']) {
318:             return $this->removeExternalPluginLoad($_GET);
319:         }
320:         unset($config['action']);
321: 
322:         // check if config should be deleted
323:         if (isset($_POST['reset'])) {
324:             $noti = new cGuiNotification();
325: 
326:             // try to delete configuration
327:             $configPath = cRegistry::getConfigValue('path', 'contenido_config');
328:             $configPath .= 'config.wysiwyg_tinymce4.php';
329:             if (cFileHandler::exists($configPath)
330:             && cFileHandler::writeable($configPath)) {
331:                 cFileHandler::remove($configPath);
332:                 $noti->displayNotification(cGuiNotification::LEVEL_INFO, i18n('TinyMCE 4 configuration got reset back to default'));
333:             } else {
334:                 // can not delete config, display message
335:                 $noti->displayNotification(cGuiNotification::LEVEL_ERROR, i18n('Can not delete config file'));
336:             }
337: 
338:             // do not save config
339:             return false;
340:         }
341: 
342:         // check if all array entries actually exist
343:         // abort if too many values are encountered
344:         $shouldArrayStructure =  array (
345:             'tinymce4_full' =>
346:             array (
347:                     'toolbar1',
348:                     'toolbar2',
349:                     'toolbar3',
350:                     'plugins'
351:             ),
352:             'tinymce4_fullscreen' =>
353:             array (
354:                     'toolbar1',
355:                     'toolbar2',
356:                     'toolbar3',
357:                     'plugins'
358:             ),
359:             'contenido_lists',
360:             'contenido_gzip',
361:             'custom',
362:         );
363:         // get name of first key
364:         reset($config);
365:         $key = key($config);
366: 
367:         if (false === isset($_POST['externalplugins']) && false === $this->_checkIsset($config[$key]['tinymce4_full'], $shouldArrayStructure['tinymce4_full'])) {
368:             $this->_configErrors[] = i18n('Fullscreen config of inline editor is erroneous.');
369:             return false;
370:         }
371:         if (false === isset($_POST['externalplugins']) && false === $this->_checkIsset($config[$key]['tinymce4_fullscreen'], $shouldArrayStructure['tinymce4_fullscreen'])) {
372:             $this->_configErrors[] = i18n('Config of editor on separate editor page is erroneous.');
373:             return false;
374:         }
375:         if (false === isset($_POST['externalplugins']) && false === isset($config[$key]['custom'])) {
376:             $this->_configErrors[] = i18n('Custom configuration of tinyMCE 4 is not set.');
377:             return false;
378:         }
379: 
380:         // do not use cRequestValidator instance because it does not support multi-dimensional arrays
381:         if (false === $this->_validateToolbarN($config[$key]['tinymce4_full']['toolbar1'])
382:         || false === $this->_validateToolbarN($config[$key]['tinymce4_full']['toolbar2'])
383:         || false === $this->_validateToolbarN($config[$key]['tinymce4_full']['toolbar3'])
384:         || false === $this->_validateToolbarN($config[$key]['tinymce4_fullscreen']['toolbar1'])
385:         || false === $this->_validateToolbarN($config[$key]['tinymce4_fullscreen']['toolbar2'])
386:         || false === $this->_validateToolbarN($config[$key]['tinymce4_fullscreen']['toolbar3'])) {
387:             $this->_configErrors[] = i18n('Toolbar(s) of editor contain erroneous data.');
388:             return false;
389:         }
390: 
391:         // remove last entry of external plugins if it is empty
392:         $lastExternalPlugin = $config[$key]['externalplugins'][count($config[$key]['externalplugins']) -1];
393:         if ('' === $lastExternalPlugin['name']
394:         && '' === $lastExternalPlugin['url']) {
395:             unset($config[$key]['externalplugins'][count($config[$key]['externalplugins']) -1]);
396:         }
397: 
398:         // custom tinymce 4 settings overwrite other fields
399:         if (cRegistry::getConfigValue('simulate_magic_quotes') === true) {
400:             $config[$key]['custom'] = stripslashes($config[$key]['custom']);
401:         }
402: 
403:         // unescape strings then build config
404:         $customConfig = (array) json_decode($config[$key]['custom'], true);
405:         switch(json_last_error()) {
406:             case JSON_ERROR_DEPTH:
407:                 $this->_configErrors[] = i18n('Maximum stack depth exceeded while decoding json');
408:             return false;
409:             case JSON_ERROR_CTRL_CHAR:
410:                 $this->_configErrors[] = i18n('Unexpected control character found');
411:             return false;
412:             case JSON_ERROR_SYNTAX:
413:                 $this->_configErrors[] = i18n('Syntax error, malformed JSON');
414:             return false;
415:         }
416: 
417:         // append new config to old config
418:         $origConfig = static::get(array(), 'raw');
419:         $config['raw'] = array_merge($origConfig, $config);
420:         //$config['raw'] = $config;
421: 
422:         // use custom parameters if they are correct JSON
423:         if (JSON_ERROR_NONE === json_last_error()) {
424:             $config[$key] = array_merge($config[$key], $customConfig);
425:         }
426:         unset($config[$key]['custom']);
427: 
428:         // put all config values into ['tinymce4']['tinymce4']
429:         // put the raw settings of config page into ['tinymce4']['raw']
430:         $origConfig = static::get(array(), 'tinymce4');
431:         $config = array_merge($origConfig, $config);
432:         $res = array('tinymce4' => array('tinymce4' =>$config));
433:         //unset($res['tinymce4']['tinymce4']['custom']);
434:         $res['tinymce4']['raw'] = $res['tinymce4']['tinymce4']['raw'];
435:         unset($res['tinymce4']['tinymce4']['raw']);
436: 
437:         // $config contains only valid content, returned processed config
438:         return $res;
439:     }
440: 
441:     /**
442:      * Do not load external plugin if user has permission to request that
443:      * @param array $form get parameters from deletion link
444:      * @return boolean|array False if data should not be saved, otherwise data to save
445:      */
446:     public function removeExternalPluginLoad($form) {
447:         // abort if user has not sufficient permissions
448:         if (false === $this->_perm) {
449:             return;
450:         }
451: 
452:         $pluginToRemoveIdx = (int) $form['external_plugin_idx'];
453: 
454:         // load config through usage of get function
455:         $settings = static::get(false);
456: 
457:         // no config or no external plugins or no plugin with that index means nothing to remove
458:         if (false === $settings
459:         || false === isset($settings['raw'])
460:         || false === isset($settings['raw']['externalplugins'])
461:         || false === isset($settings['raw']['externalplugins'][$pluginToRemoveIdx])) {
462:             return false;
463:         }
464: 
465:         // remove value from raw settings
466:         unset($settings['raw']['externalplugins'][$pluginToRemoveIdx]);
467:         // remove stray custom setting
468:         unset($settings['raw']['externalplugins']['custom']);
469: 
470:         // re-index array
471:         $settings['raw']['externalplugins'] = array_values($settings['raw']['externalplugins']);
472: 
473:         // apply raw settings to computed settings
474:         $settings['tinymce4']['externalplugins'] = $settings['raw']['externalplugins'];
475: 
476:         return array('tinymce4' => $settings);
477:     }
478: 
479:     /**
480:      * Generates an HTML form to configure tinymce 4
481:      */
482:     public function showConfigurationForm() {
483:         $page = new cGuiPage('system_wysiwyg_tinymce4', '', '5');
484:         $auth = cRegistry::getAuth();
485:         $frame = cRegistry::getFrame();
486:         $area = cRegistry::getArea();
487: 
488:         // validate if user has permission to edit this area
489:         if (false === cRegistry::getPerm()->have_perm_area_action($area, 'edit_system_wysiwyg_tinymce4')) {
490:             $page->displayCriticalError(i18n('Access denied'));
491:             $page->render();
492:             return;
493:         }
494: 
495:         if (count($this->_configErrors) > 0) {
496:             $errorMessage = i18n('The following errors occurred when trying to verify configuration:') . '<ul>';
497:             foreach ($this->_configErrors as $error) {
498:                 $errorMessage .= '<li>' . $error . '</li>';
499:             }
500:             $errorMessage .= '</ul>';
501:             $page->displayError($errorMessage);
502:         }
503: 
504:         $page->displayInfo(i18n('Currently active WYSIWYG editor: ' . cWYSIWYGEditor::getCurrentWysiwygEditorName()));
505: 
506: 
507:         $oTypeColl = new cApiTypeCollection();
508:         $oTypeColl->select();
509:         $result = '';
510:         while (false !== ($typeEntry = $oTypeColl->next())) {
511:             // specify a shortcut for type field
512:             $curType = $typeEntry->get('type');
513: 
514:             $contentTypeClassName = cTypeGenerator::getContentTypeClassName($curType);
515:             if (false === class_exists($contentTypeClassName)) {
516:                 continue;
517:             }
518:             $cContentType = new $contentTypeClassName(null, 0, array());
519:             if (false === $cContentType->isWysiwygCompatible()) {
520:                 continue;
521:             }
522: 
523: 
524:             $form = new cGuiTableForm('system_wysiwyg_tinymce4_' . strtolower($curType));
525:             $form->setAcceptCharset('UTF-8');
526: 
527:             $form->addHeader(i18n('TinyMCE 4 configuration for ') . $curType);
528: 
529:             $form->setVar('area', $area);
530:             $form->setVar('frame', $frame);
531:             $form->setVar('action', 'edit_tinymce4');
532: 
533: 
534:             $containerDiv = new cHTMLDiv();
535:             if ('CMS_HTMLHEAD' === $curType) {
536:                 $defaultToolbar1 = static::get('undo redo | consave conclose', 'raw', $curType, 'tinymce4_full', 'toolbar1');
537:                 $defaultToolbar2 = static::get('', 'raw', $curType, 'tinymce4_full', 'toolbar2');
538:                 $defaultToolbar3 = static::get('', 'raw', $curType, 'tinymce4_full', 'toolbar3');
539:                 $defaultPlugins = static::get('conclose', 'raw', $curType, 'tinymce4_full', 'plugins');
540:             } else {
541:                 $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');
542:                 $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');
543:                 $defaultToolbar3 = static::get('table | formatselect fontselect fontsizeselect | consave conclose', 'raw', $curType, 'tinymce4_full', 'toolbar3');
544:                 $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');
545:             }
546:             $containerDiv->appendContent($this->_addLabelWithTextarea('Toolbar 1:', $curType . '[tinymce4_full][toolbar1]', $defaultToolbar1));
547:             $containerDiv->appendContent($this->_addLabelWithTextarea('Toolbar 2:', $curType . '[tinymce4_full][toolbar2]', $defaultToolbar2));
548:             $containerDiv->appendContent($this->_addLabelWithTextarea('Toolbar 3:', $curType . '[tinymce4_full][toolbar3]', $defaultToolbar3));
549:             $containerDiv->appendContent($this->_addLabelWithTextarea('Plugins:', $curType . '[tinymce4_full][plugins]', $defaultPlugins));
550:             $form->add(i18n('Settings of editor in separate editor page'), $containerDiv->render());
551: 
552:             $containerDiv = new cHTMLDiv();
553:             if ('CMS_HTMLHEAD' === $curType) {
554:                 $defaultToolbar1 = static::get('undo redo | consave conclose', 'raw', $curType, 'tinymce4_inline', 'toolbar1');
555:                 $defaultToolbar2 = static::get('', 'raw', $curType, 'tinymce4_inline', 'toolbar2');
556:                 $defaultToolbar3 = static::get('', 'raw', $curType, 'tinymce4_inline', 'toolbar3');
557:                 $defaultPlugins = static::get('conclose', 'raw', $curType, 'tinymce4_inline', 'plugins');
558:             } else {
559:                 $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');
560:                 $defaultToolbar2 = static::get('', 'raw', $curType, 'tinymce4_inline', 'toolbar2');
561:                 $defaultToolbar3 = static::get('', 'raw', $curType, 'tinymce4_inline', 'toolbar3');
562:                 $defaultPlugins = static::get('conclose confullscreen media table textcolor', 'raw', $curType, 'tinymce4_inline', 'plugins');
563:             }
564:             $containerDiv->appendContent($this->_addLabelWithTextarea('Toolbar 1:', $curType . '[tinymce4_inline][toolbar1]', $defaultToolbar1));
565:             $containerDiv->appendContent($this->_addLabelWithTextarea('Toolbar 2:', $curType . '[tinymce4_inline][toolbar2]', $defaultToolbar2));
566:             $containerDiv->appendContent($this->_addLabelWithTextarea('Toolbar 3:', $curType . '[tinymce4_inline][toolbar3]', $defaultToolbar3));
567:             $containerDiv->appendContent($this->_addLabelWithTextarea('Plugins:', $curType . '[tinymce4_inline][plugins]', $defaultPlugins));
568:             $form->add(i18n('Settings of inline editor in inline mode'), $containerDiv->render());
569: 
570:             $containerDiv = new cHTMLDiv();
571:             if ('CMS_HTMLHEAD' === $curType) {
572:                 $defaultToolbar1 = static::get('undo redo | consave conclose', 'raw', $curType, 'tinymce4_fullscreen', 'toolbar1');
573:                 $defaultToolbar2 = static::get('', 'raw', $curType, 'tinymce4_fullscreen', 'toolbar2');
574:                 $defaultToolbar3 = static::get('', 'raw', $curType, 'tinymce4_fullscreen', 'toolbar3');
575:                 $defaultPlugins = static::get('conclose', 'raw', $curType, 'tinymce4_fullscreen', 'plugins');
576:             } else {
577:                 $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');
578:                 $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');
579:                 $defaultToolbar3 = static::get('table | formatselect fontselect fontsizeselect | consave conclose', 'raw', $curType, 'tinymce4_fullscreen', 'toolbar3');
580:                 $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');
581:             }
582:             $containerDiv->appendContent($this->_addLabelWithTextarea('Toolbar 1:', $curType . '[tinymce4_fullscreen][toolbar1]', $defaultToolbar1));
583:             $containerDiv->appendContent($this->_addLabelWithTextarea('Toolbar 2:', $curType . '[tinymce4_fullscreen][toolbar2]', $defaultToolbar2));
584:             $containerDiv->appendContent($this->_addLabelWithTextarea('Toolbar 3:', $curType . '[tinymce4_fullscreen][toolbar3]', $defaultToolbar3));
585:             $containerDiv->appendContent($this->_addLabelWithTextarea('Plugins:', $curType . '[tinymce4_fullscreen][plugins]', $defaultPlugins));
586:             $form->add(i18n('Settings of inline editor in fullscreen mode'), $containerDiv->render());
587: 
588:             // GZIP editor over HTTP using tinymce's library
589:             $containerDiv = new cHTMLDiv();
590:             $checked = 'contenido_gzip' === static::get(false, 'raw', $curType, 'contenido_gzip');
591:             $containerDiv->appendContent($this->_addLabelWithCheckbox(i18n('GZIP TinyMCE (only activate if server does not compress content already)'), $curType . '[contenido_gzip]', 'contenido_gzip', $checked));
592:             $form->add(i18n('contenido_gzip'), $containerDiv->render());
593: 
594:             // Add jump lists to tinymce's dialogs
595:             $containerDiv = new cHTMLDiv();
596:             $checked = true === ('image' === static::get(false, 'raw', $curType, 'contenido_lists', 'image'));
597:             $containerDiv->appendContent($this->_addLabelWithCheckbox(i18n('Provide jump lists in image insertion dialog'), $curType . '[contenido_lists][image]', 'image', $checked));
598:             $checked = true === ('link' === static::get(false, 'raw', $curType, 'contenido_lists', 'link'));
599:             $containerDiv->appendContent($this->_addLabelWithCheckbox(i18n('Provide jump lists in link insertion dialog'), $curType . '[contenido_lists][link]', 'link', $checked));
600:             $form->add(i18n('contenido_lists'), $containerDiv->render());
601: 
602:             //add textarea for custom tinymce 4 settings
603:             $textarea = new cHTMLTextarea($curType . '[custom]');
604:             $textarea->setAttribute('style', 'width: 99%;');
605:             $defaultParams = '';
606:             if ('CMS_HTMLHEAD' === $curType) {
607:                 $defaultParams = '{' . PHP_EOL . '"inline": true,' . PHP_EOL . '"menubar": false' . PHP_EOL . '}';
608:             }
609:             $textarea->setValue(static::get($defaultParams, 'raw', $curType, 'custom'));
610:             $form->add(i18n('Additional parameters (JSON passed to tinymce constructor)'), $textarea->render());
611: 
612:             // check permission to save system wysiwyg editor settings
613:             if (false === $this->_perm) {
614:                 $form->setActionButton('submit', cRegistry::getBackendUrl() . 'images/but_ok_off.gif', i18n("You are not sysadmin. You can't change these settings."), 's');
615:             }
616:             $result .= '<p>' . $form->render() . '</p>';
617:         }
618: 
619:         // external plugins (can not be configured per CMS-type)
620:         $form = new cGuiTableForm('system_wysiwyg_tinymce4_external_plugins');
621:         $form->setAcceptCharset('UTF-8');
622:         $form->addHeader(i18n('TinyMCE 4 configuration for external plugins'));
623: 
624:         $form->setVar('area', $area);
625:         $form->setVar('frame', $frame);
626:         $form->setVar('action', 'edit_tinymce4');
627:         $containerDiv = new cHTMLDiv();
628:         $containerDiv->appendContent($this->_listExternalPlugins());
629:         $form->add(i18n('External plugins to load'), $containerDiv);
630:         $result .= '<p>' . $form->render() . '</p>';
631: 
632:         $configPath = cRegistry::getConfigValue('path', 'contenido_config');
633:         $configPath .= 'config.wysiwyg_tinymce4.php';
634:         if (cFileHandler::exists($configPath)
635:         && cFileHandler::writeable($configPath)) {
636:             $resetForm = new cHTMLForm('system_wysiwyg_tinymce4_general_options', 'main.php', 'post');
637:             $resetForm->setVar('area', $area);
638:             $resetForm->setVar('frame', $frame);
639:             $resetForm->setVar('action', 'edit_tinymce4');
640:             $oResetButton = new cHTMLButton('reset', i18n('Reset configuration back to default'));
641:             $oResetButton->setAttribute('value', i18n('Reset Configuration'));
642: 
643:             $resetForm = $resetForm->appendContent($oResetButton);
644:             $result .= $resetForm->render();
645:         }
646: 
647: 
648:         $page->set('s', 'FORM', $result);
649:         $page->set('s', 'RELOAD_HEADER', (false) ? 'true' : 'false');
650:         $page->render();
651:     }
652: }
653: 
CMS CONTENIDO 4.9.8 API documentation generated by ApiGen 2.8.0