blog && $core->auth->check($permissions, $core->blog->id)) { return; } // Check if dashboard is not the current page et if it is granted for the user if (!$home && $core->blog && $core->auth->check('usage,contentadmin', $core->blog->id)) { // Go back to the dashboard http::redirect(DC_ADMIN_URL); } if (session_id()) { $core->session->destroy(); } http::redirect(DC_AUTH_PAGE); } # Check super admin public static function checkSuper($home = false) { $core = self::getCore(); if (!$core->auth->isSuperAdmin()) { // Check if dashboard is not the current page et if it is granted for the user if (!$home && $core->blog && $core->auth->check('usage,contentadmin', $core->blog->id)) { // Go back to the dashboard http::redirect(DC_ADMIN_URL); } if (session_id()) { $core->session->destroy(); } http::redirect(DC_AUTH_PAGE); } } # Top of admin page public static function open($title = '', $head = '', $breadcrumb = '', $options = []) { $core = self::getCore(); $js = []; # List of user's blogs if ($core->auth->getBlogCount() == 1 || $core->auth->getBlogCount() > 20) { $blog_box = '

' . __('Blog:') . ' ' . html::escapeHTML($core->blog->name) . ''; if ($core->auth->getBlogCount() > 20) { $blog_box .= ' - ' . __('Change blog') . ''; } $blog_box .= '

'; } else { $rs_blogs = $core->getBlogs(['order' => 'LOWER(blog_name)', 'limit' => 20]); $blogs = []; while ($rs_blogs->fetch()) { $blogs[html::escapeHTML($rs_blogs->blog_name . ' - ' . $rs_blogs->blog_url)] = $rs_blogs->blog_id; } $blog_box = '

' . $core->formNonce() . form::combo('switchblog', $blogs, $core->blog->id) . form::hidden(['redir'], $_SERVER['REQUEST_URI']) . '

'; } $safe_mode = isset($_SESSION['sess_safe_mode']) && $_SESSION['sess_safe_mode']; # Display $headers = new ArrayObject([]); # Content-Type $headers['content-type'] = 'Content-Type: text/html; charset=UTF-8'; # Referrer Policy for admin pages $headers['referrer'] = 'Referrer-Policy: strict-origin'; # Prevents Clickjacking as far as possible if (isset($options['x-frame-allow'])) { self::setXFrameOptions($headers, $options['x-frame-allow']); } else { self::setXFrameOptions($headers); } # Content-Security-Policy (only if safe mode if not active, it may help) if (!$safe_mode && $core->blog->settings->system->csp_admin_on) { // Get directives from settings if exist, else set defaults $csp = new ArrayObject([]); // SQlite Clearbricks driver does not allow using single quote at beginning or end of a field value // so we have to use neutral values (localhost and 127.0.0.1) for some CSP directives $csp_prefix = $core->con->syntax() == 'sqlite' ? 'localhost ' : ''; // Hack for SQlite Clearbricks syntax $csp_suffix = $core->con->syntax() == 'sqlite' ? ' 127.0.0.1' : ''; // Hack for SQlite Clearbricks syntax $csp['default-src'] = $core->blog->settings->system->csp_admin_default ?: $csp_prefix . "'self'" . $csp_suffix; $csp['script-src'] = $core->blog->settings->system->csp_admin_script ?: $csp_prefix . "'self' 'unsafe-eval'" . $csp_suffix; $csp['style-src'] = $core->blog->settings->system->csp_admin_style ?: $csp_prefix . "'self' 'unsafe-inline'" . $csp_suffix; $csp['img-src'] = $core->blog->settings->system->csp_admin_img ?: $csp_prefix . "'self' data: http://media.dotaddict.org blob:"; # Cope with blog post preview (via public URL in iframe) if (!is_null($core->blog->host)) { $csp['default-src'] .= ' ' . parse_url($core->blog->host, PHP_URL_HOST); $csp['script-src'] .= ' ' . parse_url($core->blog->host, PHP_URL_HOST); $csp['style-src'] .= ' ' . parse_url($core->blog->host, PHP_URL_HOST); } # Cope with media display in media manager (via public URL) if (!is_null($core->media)) { $csp['img-src'] .= ' ' . parse_url($core->media->root_url, PHP_URL_HOST); } elseif (!is_null($core->blog->host)) { // Let's try with the blog URL $csp['img-src'] .= ' ' . parse_url($core->blog->host, PHP_URL_HOST); } # Allow everything in iframe (used by editors to preview public content) $csp['child-src'] = "*"; # --BEHAVIOR-- adminPageHTTPHeaderCSP $core->callBehavior('adminPageHTTPHeaderCSP', $csp); // Construct CSP header $directives = []; foreach ($csp as $key => $value) { if ($value) { $directives[] = $key . ' ' . $value; } } if (count($directives)) { if (version_compare(phpversion(), '5.4', '>=')) { // csp_report.php needs PHP ≥ 5.4 $directives[] = "report-uri " . DC_ADMIN_URL . "csp_report.php"; } $report_only = ($core->blog->settings->system->csp_admin_report_only) ? '-Report-Only' : ''; $headers['csp'] = "Content-Security-Policy" . $report_only . ": " . implode(" ; ", $directives); } } # --BEHAVIOR-- adminPageHTTPHeaders $core->callBehavior('adminPageHTTPHeaders', $headers); foreach ($headers as $key => $value) { header($value); } echo '' . '' . "\n" . "\n" . ' ' . "\n" . ' ' . "\n" . ' ' . "\n" . ' ' . "\n" . ' ' . $title . ' - ' . html::escapeHTML($core->blog->name) . ' - ' . html::escapeHTML(DC_VENDOR_NAME) . ' - ' . DC_VERSION . '' . "\n"; if ($core->auth->user_prefs->interface->darkmode) { $js['darkMode'] = 1; echo self::cssLoad('style/default-dark.css'); } else { $js['darkMode'] = 0; echo self::cssLoad('style/default.css'); } if (l10n::getTextDirection($GLOBALS['_lang']) == 'rtl') { echo self::cssLoad('style/default-rtl.css'); } $core->auth->user_prefs->addWorkspace('interface'); if (!$core->auth->user_prefs->interface->hide_std_favicon) { echo '' . "\n" . '' . "\n"; } if ($core->auth->user_prefs->interface->htmlfontsize) { $js['htmlFontSize'] = $core->auth->user_prefs->interface->htmlfontsize; } $js['hideMoreInfo'] = (boolean) $core->auth->user_prefs->interface->hidemoreinfo; $js['showAjaxLoader'] = (boolean) $core->auth->user_prefs->interface->showajaxloader; $core->auth->user_prefs->addWorkspace('accessibility'); $js['noDragDrop'] = (boolean) $core->auth->user_prefs->accessibility->nodragdrop; // Set some JSON data echo dcUtils::jsJson('dotclear_init', $js); echo self::jsCommon() . self::jsToggles() . $head; # --BEHAVIOR-- adminPageHTMLHead $core->callBehavior('adminPageHTMLHead'); echo "\n" . '' . "\n" . '' . "\n" . ''; // end header echo '
' . "\n" . '
' . '
' . "\n" . '
' . "\n"; # Safe mode if ($safe_mode) { echo ''; } // Display breadcrumb (if given) before any error messages echo $breadcrumb; // Display notices and errors echo $core->notices->getNotices(); } /** @deprecated Please use $core->notices->getNotices() **/ public static function notices() { $core = self::getCore(); return $core->notices->getNotices(); } /** @deprecated Please use $core->notices->addNotice() **/ public static function addNotice($type, $message, $options = []) { $core = self::getCore(); $core->notices->addNotice($type, $message, $options); } /** @deprecated Please use $core->notices->addSuccessNotice() **/ public static function addSuccessNotice($message, $options = []) { self::addNotice("success", $message, $options); } /** @deprecated Please use $core->notices->addWarningNotice() **/ public static function addWarningNotice($message, $options = []) { self::addNotice("warning", $message, $options); } /** @deprecated Please use $core->notices->addErrorNotice() **/ public static function addErrorNotice($message, $options = []) { self::addNotice("error", $message, $options); } public static function close() { $core = self::getCore(); if (!$GLOBALS['__resources']['ctxhelp']) { if (!$core->auth->user_prefs->interface->hidehelpbutton) { echo '

' . __('Global help') . '

'; } } $menu = &$GLOBALS['_menu']; echo "
\n" . // End of #content "
\n" . // End of #main '' . "\n" . // End of #main-menu "
\n"; // End of #wrapper echo '

' . __('Page top') . '

' . "\n"; $figure = " ♥‿♥ | | | )_) )_) )_) )___))___))___)\ )____)____)_____)\\ _____|____|____|____\\\__ ---------\ /--------- ^^^^^ ^^^^^^^^^^^^^^^^^^^^^ ^^^^ ^^^^ ^^^ ^^ ^^^^ ^^^ "; echo '' . "\n" . "" . "\n"; if (defined('DC_DEV') && DC_DEV === true) { echo self::debugInfo(); } echo ''; } public static function openPopup($title = '', $head = '', $breadcrumb = '') { $core = self::getCore(); $js = []; # Display header('Content-Type: text/html; charset=UTF-8'); # Referrer Policy for admin pages header('Referrer-Policy: strict-origin'); # Prevents Clickjacking as far as possible header('X-Frame-Options: SAMEORIGIN'); // FF 3.6.9+ Chrome 4.1+ IE 8+ Safari 4+ Opera 10.5+ echo '' . '' . "\n" . "\n" . ' ' . "\n" . ' ' . "\n" . ' ' . $title . ' - ' . html::escapeHTML($core->blog->name) . ' - ' . html::escapeHTML(DC_VENDOR_NAME) . ' - ' . DC_VERSION . '' . "\n" . ' ' . "\n" . ' ' . "\n"; if ($core->auth->user_prefs->interface->darkmode) { $js['darkMode'] = 1; echo self::cssLoad('style/default-dark.css'); } else { $js['darkMode'] = 0; echo self::cssLoad('style/default.css'); } if (l10n::getTextDirection($GLOBALS['_lang']) == 'rtl') { echo self::cssLoad('style/default-rtl.css'); } $core->auth->user_prefs->addWorkspace('interface'); if ($core->auth->user_prefs->interface->htmlfontsize) { $js['htmlFontSize'] = $core->auth->user_prefs->interface->htmlfontsize; } $js['hideMoreInfo'] = (boolean) $core->auth->user_prefs->interface->hidemoreinfo; $js['showAjaxLoader'] = (boolean) $core->auth->user_prefs->interface->showajaxloader; $core->auth->user_prefs->addWorkspace('accessibility'); $js['noDragDrop'] = (boolean) $core->auth->user_prefs->accessibility->nodragdrop; // Set JSON data echo dcUtils::jsJson('dotclear_init', $js); echo self::jsCommon() . self::jsToggles() . $head; # --BEHAVIOR-- adminPageHTMLHead $core->callBehavior('adminPageHTMLHead'); echo "\n" . '' . "\n" . '

' . DC_VENDOR_NAME . '

' . "\n"; echo '
' . "\n" . '
' . "\n" . '
' . "\n"; // display breadcrumb if given echo $breadcrumb; // Display notices and errors echo $core->notices->getNotices(); } public static function closePopup() { echo "
\n" . // End of #content "
\n" . // End of #main "
\n" . // End of #wrapper '

' . __('Page top') . '

' . "\n" . '' . "\n" . ''; } public static function breadcrumb($elements = null, $options = []) { $core = self::getCore(); $with_home_link = isset($options['home_link']) ? $options['home_link'] : true; $hl = isset($options['hl']) ? $options['hl'] : true; $hl_pos = isset($options['hl_pos']) ? $options['hl_pos'] : -1; // First item of array elements should be blog's name, System or Plugins $res = '

' . ($with_home_link ? '' . __('Go to dashboard') . '' : ''); $index = 0; if ($hl_pos < 0) { $hl_pos = count($elements) + $hl_pos; } foreach ($elements as $element => $url) { if ($hl && $index == $hl_pos) { $element = sprintf('%s', $element); } $res .= ($with_home_link ? ($index == 1 ? ' : ' : ' › ') : ($index == 0 ? ' ' : ' › ')) . ($url ? '' : '') . $element . ($url ? '' : ''); $index++; } $res .= '

'; return $res; } /** @deprecated Please use $core->notices->message() **/ public static function message($msg, $timestamp = true, $div = false, $echo = true, $class = 'message') { $core = self::getCore(); return $core->notices->message($msg, $timestamp, $div, $echo, $class); } /** @deprecated Please use $core->notices->success() **/ public static function success($msg, $timestamp = true, $div = false, $echo = true) { return self::message($msg, $timestamp, $div, $echo, "success"); } /** @deprecated Please use $core->notices->warning() **/ public static function warning($msg, $timestamp = true, $div = false, $echo = true) { return self::message($msg, $timestamp, $div, $echo, "warning-msg"); } private static function debugInfo() { $global_vars = implode(', ', array_keys($GLOBALS)); $res = '
' . '

memory usage: ' . memory_get_usage() . ' (' . files::size(memory_get_usage()) . ')

'; if (function_exists('xdebug_get_profiler_filename')) { $res .= '

Elapsed time: ' . xdebug_time_index() . ' seconds

'; $prof_file = xdebug_get_profiler_filename(); if ($prof_file) { $res .= '

Profiler file : ' . xdebug_get_profiler_filename() . '

'; } else { $prof_url = http::getSelfURI(); $prof_url .= (strpos($prof_url, '?') === false) ? '?' : '&'; $prof_url .= 'XDEBUG_PROFILE'; $res .= '

Trigger profiler

'; } /* xdebug configuration: zend_extension = /.../xdebug.so xdebug.auto_trace = On xdebug.trace_format = 0 xdebug.trace_options = 1 xdebug.show_mem_delta = On xdebug.profiler_enable = 0 xdebug.profiler_enable_trigger = 1 xdebug.profiler_output_dir = /tmp xdebug.profiler_append = 0 xdebug.profiler_output_name = timestamp */ } $res .= '

Global vars: ' . $global_vars . '

' . '
'; return $res; } public static function help($page, $index = '') { # Deprecated but we keep this for plugins. } public static function helpBlock(...$params) { $core = self::getCore(); if ($core->auth->user_prefs->interface->hidehelpbutton) { return; } $args = new ArrayObject($params); # --BEHAVIOR-- adminPageHelpBlock $core->callBehavior('adminPageHelpBlock', $args); if (empty($args)) { return; }; global $__resources; if (empty($__resources['help'])) { return; } $content = ''; foreach ($args as $v) { if (is_object($v) && isset($v->content)) { $content .= $v->content; continue; } if (!isset($__resources['help'][$v])) { continue; } $f = $__resources['help'][$v]; if (!file_exists($f) || !is_readable($f)) { continue; } $fc = file_get_contents($f); if (preg_match('|]*?>(.*?)|ms', $fc, $matches)) { $content .= $matches[1]; } else { $content .= $fc; } } if (trim($content) == '') { return; } // Set contextual help global flag $GLOBALS['__resources']['ctxhelp'] = true; echo '

' . __('Help about this page') . '

' . $content . '
' . '
'; } public static function cssLoad($src, $media = 'screen', $v = '') { $escaped_src = html::escapeHTML($src); if (!isset(self::$loaded_css[$escaped_src])) { self::$loaded_css[$escaped_src] = true; $escaped_src = self::appendVersion($escaped_src, $v); return '' . "\n"; } } public static function jsLoad($src, $v = '') { $escaped_src = html::escapeHTML($src); if (!isset(self::$loaded_js[$escaped_src])) { self::$loaded_js[$escaped_src] = true; $escaped_src = self::appendVersion($escaped_src, $v); return '' . "\n"; } } private static function appendVersion($src, $v = '') { $src .= (strpos($src, '?') === false ? '?' : '&') . 'v='; if (defined('DC_DEV') && DC_DEV === true) { $src .= md5(uniqid()); } else { $src .= ($v === '' ? DC_VERSION : $v); } return $src; } /** * return a javascript variable definition line code * * @deprecated 2.15 use dcPage::jsJson() and getData()/mergeDeep() in javascript * * @param string $n variable name * @param various $v value * * @return string javascript code */ public static function jsVar($n, $v) { return $n . " = '" . html::escapeJS($v) . "';\n"; } /** * return a list of javascript variables définitions code * * @deprecated 2.15 use dcPage::jsJson() and getData()/mergeDeep() in javascript * * @param array $vars The variables * * @return string javascript code (inside ) */ public static function jsVars($vars) { $ret = '\n"; return $ret; } public static function jsJson($id, $vars) { return dcUtils::jsJson($id, $vars); } public static function jsToggles() { $core = self::getCore(); $js = []; if ($core->auth->user_prefs->toggles) { $unfolded_sections = explode(',', $core->auth->user_prefs->toggles->unfolded_sections); foreach ($unfolded_sections as $k => &$v) { if ($v !== '') { $js[$unfolded_sections[$k]] = true; } } } return self::jsJson('dotclear_toggles', $js) . self::jsLoad('js/toggles.js'); } public static function jsCommon() { $core = self::getCore(); $js = [ 'nonce' => $core->getNonce(), 'img_plus_src' => 'images/expand.png', 'img_plus_txt' => '►', 'img_plus_alt' => __('uncover'), 'img_minus_src' => 'images/hide.png', 'img_minus_txt' => '▼', 'img_minus_alt' => __('hide'), 'img_menu_on' => 'images/menu_on.png', 'img_menu_off' => 'images/menu_off.png', 'img_plus_theme_src' => 'images/plus-theme.png', 'img_plus_theme_txt' => '►', 'img_plus_theme_alt' => __('uncover'), 'img_minus_theme_src' => 'images/minus-theme.png', 'img_minus_theme_txt' => '▼', 'img_minus_theme_alt' => __('hide') ]; $js_msg = [ 'help' => __('Need help?'), 'new_window' => __('new window'), 'help_hide' => __('Hide'), 'to_select' => __('Select:'), 'no_selection' => __('no selection'), 'select_all' => __('select all'), 'invert_sel' => __('Invert selection'), 'website' => __('Web site:'), 'email' => __('Email:'), 'ip_address' => __('IP address:'), 'error' => __('Error:'), 'entry_created' => __('Entry has been successfully created.'), 'edit_entry' => __('Edit entry'), 'view_entry' => __('view entry'), 'confirm_delete_posts' => __("Are you sure you want to delete selected entries (%s)?"), 'confirm_delete_medias' => __("Are you sure you want to delete selected medias (%d)?"), 'confirm_delete_categories' => __("Are you sure you want to delete selected categories (%s)?"), 'confirm_delete_post' => __("Are you sure you want to delete this entry?"), 'click_to_unlock' => __("Click here to unlock the field"), 'confirm_spam_delete' => __('Are you sure you want to delete all spams?'), 'confirm_delete_comments' => __('Are you sure you want to delete selected comments (%s)?'), 'confirm_delete_comment' => __('Are you sure you want to delete this comment?'), 'cannot_delete_users' => __('Users with posts cannot be deleted.'), 'confirm_delete_user' => __('Are you sure you want to delete selected users (%s)?'), 'confirm_delete_blog' => __('Are you sure you want to delete selected blogs (%s)?'), 'confirm_delete_category' => __('Are you sure you want to delete category "%s"?'), 'confirm_reorder_categories' => __('Are you sure you want to reorder all categories?'), 'confirm_delete_media' => __('Are you sure you want to remove media "%s"?'), 'confirm_delete_directory' => __('Are you sure you want to remove directory "%s"?'), 'confirm_extract_current' => __('Are you sure you want to extract archive in current directory?'), 'confirm_remove_attachment' => __('Are you sure you want to remove attachment "%s"?'), 'confirm_delete_lang' => __('Are you sure you want to delete "%s" language?'), 'confirm_delete_plugin' => __('Are you sure you want to delete "%s" plugin?'), 'confirm_delete_plugins' => __('Are you sure you want to delete selected plugins?'), 'use_this_theme' => __('Use this theme'), 'remove_this_theme' => __('Remove this theme'), 'confirm_delete_theme' => __('Are you sure you want to delete "%s" theme?'), 'confirm_delete_themes' => __('Are you sure you want to delete selected themes?'), 'confirm_delete_backup' => __('Are you sure you want to delete this backup?'), 'confirm_revert_backup' => __('Are you sure you want to revert to this backup?'), 'zip_file_content' => __('Zip file content'), 'xhtml_validator' => __('XHTML markup validator'), 'xhtml_valid' => __('XHTML content is valid.'), 'xhtml_not_valid' => __('There are XHTML markup errors.'), 'warning_validate_no_save_content' => __('Attention: an audit of a content not yet registered.'), 'confirm_change_post_format' => __('You have unsaved changes. Switch post format will loose these changes. Proceed anyway?'), 'confirm_change_post_format_noconvert' => __("Warning: post format change will not convert existing content. You will need to apply new format by yourself. Proceed anyway?"), 'load_enhanced_uploader' => __('Loading enhanced uploader, please wait.'), 'module_author' => __('Author:'), 'module_details' => __('Details'), 'module_support' => __('Support'), 'module_help' => __('Help:'), 'module_section' => __('Section:'), 'module_tags' => __('Tags:'), 'close_notice' => __('Hide this notice') ]; return self::jsLoad('js/prepend.js') . self::jsLoad('js/jquery/jquery.js') . self::jsJson('dotclear_jquery', [ 'mute' => (empty($core->blog) || $core->blog->settings->system->jquery_migrate_mute) ]) . self::jsLoad('js/jquery-mute.js') . self::jsLoad('js/jquery/jquery-migrate.js') . self::jsLoad('js/jquery/jquery.biscuit.js') . self::jsJson('dotclear', $js) . self::jsJson('dotclear_msg', $js_msg) . self::jsLoad('js/common.js') . self::jsLoad('js/services.js') . self::jsLoad('js/prelude.js'); } /** @deprecated since version 2.11 */ public static function jsLoadIE7() { return ''; } public static function jsConfirmClose(...$args) { $js = [ 'prompt' => __('You have unsaved changes.'), 'forms' => $args ]; return self::jsJson('confirm_close', $js) . self::jsLoad('js/confirm-close.js'); } public static function jsPageTabs($default = null) { $js = [ 'default' => $default ]; return self::jsJson('page_tabs', $js) . self::jsLoad('js/jquery/jquery.pageTabs.js') . self::jsLoad('js/page-tabs.js'); } public static function jsModal() { return self::jsLoad('js/jquery/jquery.magnific-popup.js'); } public static function jsColorPicker() { return self::cssLoad('style/farbtastic/farbtastic.css') . self::jsLoad('js/jquery/jquery.farbtastic.js') . self::jsLoad('js/color-picker.js'); } public static function jsDatePicker() { $js = [ 'months' => [ __('January'), __('February'), __('March'), __('April'), __('May'), __('June'), __('July'), __('August'), __('September'), __('October'), __('November'), __('December') ], 'days' => [ __('Monday'), __('Tuesday'), __('Wednesday'), __('Thursday'), __('Friday'), __('Saturday'), __('Sunday') ], 'img_src' => 'images/date-picker.png', 'img_alt' => __('Choose date'), 'close_msg' => __('close'), 'now_msg' => __('now') ]; return self::cssLoad('style/date-picker.css') . self::jsJson('date_picker', $js) . self::jsLoad('js/date-picker.js'); } public static function jsToolBar() { # Deprecated but we keep this for plugins. } public static function jsUpload($params = [], $base_url = null) { $core = self::getCore(); if (!$base_url) { $base_url = path::clean(dirname(preg_replace('/(\?.*$)?/', '', $_SERVER['REQUEST_URI']))) . '/'; } $params = array_merge($params, [ 'sess_id=' . session_id(), 'sess_uid=' . $_SESSION['sess_browser_uid'], 'xd_check=' . $core->getNonce() ]); $js_msg = [ 'enhanced_uploader_activate' => __('Temporarily activate enhanced uploader'), 'enhanced_uploader_disable' => __('Temporarily disable enhanced uploader') ]; $js = [ 'msg' => [ 'limit_exceeded' => __('Limit exceeded.'), 'size_limit_exceeded' => __('File size exceeds allowed limit.'), 'canceled' => __('Canceled.'), 'http_error' => __('HTTP Error:'), 'error' => __('Error:'), 'choose_file' => __('Choose file'), 'choose_files' => __('Choose files'), 'cancel' => __('Cancel'), 'clean' => __('Clean'), 'upload' => __('Upload'), 'send' => __('Send'), 'file_successfully_uploaded' => __('File successfully uploaded.'), 'no_file_in_queue' => __('No file in queue.'), 'file_in_queue' => __('1 file in queue.'), 'files_in_queue' => __('%d files in queue.'), 'queue_error' => __('Queue error:') ], 'base_url' => $base_url ]; return self::jsJson('file_upload', $js) . self::jsJson('file_upload_msg', $js_msg) . self::jsLoad('js/file-upload.js') . self::jsLoad('js/jquery/jquery-ui.custom.js') . self::jsLoad('js/jsUpload/tmpl.js') . self::jsLoad('js/jsUpload/template-upload.js') . self::jsLoad('js/jsUpload/template-download.js') . self::jsLoad('js/jsUpload/load-image.js') . self::jsLoad('js/jsUpload/jquery.iframe-transport.js') . self::jsLoad('js/jsUpload/jquery.fileupload.js') . self::jsLoad('js/jsUpload/jquery.fileupload-process.js') . self::jsLoad('js/jsUpload/jquery.fileupload-resize.js') . self::jsLoad('js/jsUpload/jquery.fileupload-ui.js'); } public static function jsMetaEditor() { return self::jsLoad('js/meta-editor.js'); } public static function jsFilterControl($show = true) { $js = [ 'show_filters' => (boolean) $show, 'filter_posts_list' => __('Show filters and display options'), 'cancel_the_filter' => __('Cancel filters and display options') ]; return self::jsJson('filter_controls', $js) . self::jsLoad('js/filter-controls.js'); } public static function jsLoadCodeMirror($theme = '', $multi = true, $modes = ['css', 'htmlmixed', 'javascript', 'php', 'xml']) { $ret = self::cssLoad('js/codemirror/lib/codemirror.css') . self::jsLoad('js/codemirror/lib/codemirror.js'); if ($multi) { $ret .= self::jsLoad('js/codemirror/addon/mode/multiplex.js'); } foreach ($modes as $mode) { $ret .= self::jsLoad('js/codemirror/mode/' . $mode . '/' . $mode . '.js'); } $ret .= self::jsLoad('js/codemirror/addon/edit/closebrackets.js') . self::jsLoad('js/codemirror/addon/edit/matchbrackets.js') . self::cssLoad('js/codemirror/addon/display/fullscreen.css') . self::jsLoad('js/codemirror/addon/display/fullscreen.js'); if ($theme != '') { $ret .= self::cssLoad('js/codemirror/theme/' . $theme . '.css'); } return $ret; } public static function jsRunCodeMirror($name, $id = null, $mode = null, $theme = '') { if (is_array($name)) { $js = $name; } else { $js = [[ 'name' => $name, 'id' => $id, 'mode' => $mode, 'theme' => $theme ]]; } $ret = self::jsJson('codemirror', $js) . self::jsLoad('js/codemirror.js'); return $ret; } public static function getCodeMirrorThemes() { $themes = []; $themes_root = dirname(__FILE__) . '/../../admin' . '/js/codemirror/theme/'; if (is_dir($themes_root) && is_readable($themes_root)) { if (($d = @dir($themes_root)) !== false) { while (($entry = $d->read()) !== false) { if ($entry != '.' && $entry != '..' && substr($entry, 0, 1) != '.' && is_readable($themes_root . '/' . $entry)) { $themes[] = substr($entry, 0, -4); // remove .css extension } } sort($themes); } } return $themes; } public static function getPF($file) { $core = self::getCore(); return $core->adminurl->get('load.plugin.file', ['pf' => $file]); } public static function getVF($file) { $core = self::getCore(); return $core->adminurl->get('load.var.file', ['vf' => $file]); } public static function setXFrameOptions($headers, $origin = null) { if (self::$xframe_loaded) { return; } if ($origin !== null) { $url = parse_url($origin); $headers['x-frame-options'] = sprintf('X-Frame-Options: %s', is_array($url) && isset($url['host']) ? ("ALLOW-FROM " . (isset($url['scheme']) ? $url['scheme'] . ':' : '') . '//' . $url['host']) : 'SAMEORIGIN'); } else { $headers['x-frame-options'] = 'X-Frame-Options: SAMEORIGIN'; // FF 3.6.9+ Chrome 4.1+ IE 8+ Safari 4+ Opera 10.5+ } self::$xframe_loaded = true; } }