function announce($thing) { // $thing[0]: message text // $thing[1]: message type, defaults to "success" unless empty or a different flag is set if ($thing === '') { return ''; } if (!is_array($thing) || !isset($thing[1])) { $thing = array($thing, 0); } switch ($thing[1]) { case E_ERROR: $class = 'error'; break; case E_WARNING: $class = 'warning'; break; default: $class = 'success'; break; } $html = "<span id='message' class='{$class}'>" . gTxt($thing[0]) . '</span>'; // Try to inject $html into the message pane no matter when announce()'s output is printed $js = addslashes($html); $js = <<<EOS \t\t\$(document).ready( function(){ \t \t\t\$("#messagepane").html("{$js}"); \t\t\t\$('#messagepane #message.error').fadeOut(800).fadeIn(800); \t\t\t\$('#messagepane #message.warning').fadeOut(800).fadeIn(800); \t\t} ) EOS; return script_js(str_replace('</', '<\\/', $js), $html); }
/** * Renders and outputs a login form. * * This function outputs a full HTML document, * including <head> and footer. * * @param string|array $message The activity message */ function doLoginForm($message) { global $textarray_script, $event, $step; include txpath . '/lib/txplib_head.php'; $event = 'login'; if (gps('logout')) { $step = 'logout'; } elseif (gps('reset')) { $step = 'reset'; } pagetop(gTxt('login'), $message); $stay = (cs('txp_login') and !gps('logout') ? 1 : 0); $reset = gps('reset'); $name = join(',', array_slice(explode(',', cs('txp_login')), 0, -1)); $out = array(); if ($reset) { $out[] = hed(gTxt('password_reset'), 2, array('id' => 'txp-login-heading')) . graf(n . span(tag(gTxt('name'), 'label', array('for' => 'login_name')), array('class' => 'txp-label')) . n . span(fInput('text', 'p_userid', $name, '', '', '', INPUT_REGULAR, '', 'login_name'), array('class' => 'txp-value')), ' class="login-name"') . graf(fInput('submit', '', gTxt('password_reset_button'), 'publish') . n) . graf(href(gTxt('back_to_login'), 'index.php'), array('class' => 'login-return')) . hInput('p_reset', 1); } else { $out[] = hed(gTxt('login_to_textpattern'), 2, array('id' => 'txp-login-heading')) . graf(n . span(tag(gTxt('name'), 'label', array('for' => 'login_name')), array('class' => 'txp-label')) . n . span(fInput('text', 'p_userid', $name, '', '', '', INPUT_REGULAR, '', 'login_name'), array('class' => 'txp-value')), array('class' => 'login-name')) . graf(n . span(tag(gTxt('password'), 'label', array('for' => 'login_password')), array('class' => 'txp-label')) . n . span(fInput('password', 'p_password', '', '', '', '', INPUT_REGULAR, '', 'login_password'), array('class' => 'txp-value')), array('class' => 'login-password')) . graf(checkbox('stay', 1, $stay, '', 'login_stay') . n . tag(gTxt('stay_logged_in'), 'label', array('for' => 'login_stay')) . popHelp('remember_login') . n, array('class' => 'login-stay')) . graf(fInput('submit', '', gTxt('log_in_button'), 'publish') . n) . graf(href(gTxt('password_forgotten'), '?reset=1'), array('class' => 'login-forgot')); if (gps('event')) { $out[] = eInput(gps('event')); } } echo form(tag(join('', $out), 'section', array('role' => 'region', 'class' => 'txp-login', 'aria-labelledby' => 'txp-login-heading')), '', '', 'post', '', '', 'login_form') . script_js('textpattern.textarray = ' . json_encode($textarray_script)) . n . '</main><!-- /txp-body -->' . n . '</body>' . n . '</html>'; exit(0); }
/** * Weave the current template and show it ready to paste. */ static function export() { $f = file_get_contents(txpath . self::$template); foreach (self::$what as $table => $columns) { $tick = '`'; $cols = empty($columns) ? '*' : $tick . join('`,`', doSlash($columns)) . $tick; $rs = safe_rows($cols, $table, (empty($columns) ? '1=1' : $columns[0] . ' not like \'%.min%\'') . (empty($columns) ? '' : ' ORDER BY `' . $columns[0] . '`')); $rows = array(); foreach ($rs as $a) { // Enforce *nix new-lines $a = str_replace("\r\n", "\n", $a); // Literal backslash into corresponding MySQL literal foreach ($a as &$v) { $v = addcslashes(addcslashes($v, '\\'), '\\'); } $a = "'" . join("', '", doSlash($a)) . "'"; $rows[] = self::$where . ' = "INSERT INTO `".PFX."' . $table . '`(' . $cols . ') VALUES(' . $a . ')";'; } $f = preg_replace("#(// sql:{$table}).*(// /sql:{$table})#s", '$1' . n . join(n, $rows) . n . '$2', $f); } echo text_area('code', 600, '', $f, 'code'); echo script_js(<<<EOS \t\t\$('#code').focus(function() { \t\t\tthis.select(); \t\t}); EOS ); }
function html_head() { $js = <<<SF \t\t\t\$(document).ready( function() { \t\t\t\t\$("#nav li").hover( function() { \$(this).addClass("sfhover"); }, function() { \$(this).removeClass("sfhover"); } ); \t\t\t}); SF; return parent::html_head() . n . script_js($js) . n; }
function plugin_list($message = '') { global $event; pagetop(gTxt('tab_plugins'), $message); echo '<h1 class="txp-heading">' . gTxt('tab_plugins') . '</h1>'; echo '<div id="' . $event . '_control" class="txp-control-panel">'; echo n . plugin_form() . n . '</div>'; extract(gpsa(array('sort', 'dir'))); if ($sort === '') { $sort = get_pref('plugin_sort_column', 'name'); } if ($dir === '') { $dir = get_pref('plugin_sort_dir', 'asc'); } $dir = $dir == 'desc' ? 'desc' : 'asc'; if (!in_array($sort, array('name', 'status', 'author', 'version', 'modified', 'load_order'))) { $sort = 'name'; } $sort_sql = $sort . ' ' . $dir; set_pref('plugin_sort_column', $sort, 'plugin', 2, '', 0, PREF_PRIVATE); set_pref('plugin_sort_dir', $dir, 'plugin', 2, '', 0, PREF_PRIVATE); $switch_dir = $dir == 'desc' ? 'asc' : 'desc'; $rs = safe_rows_start('name, status, author, author_uri, version, description, length(help) as help, abs(strcmp(md5(code),code_md5)) as modified, load_order, flags', 'txp_plugin', '1 order by ' . $sort_sql); if ($rs and numRows($rs) > 0) { echo n . '<div id="' . $event . '_container" class="txp-container">'; echo '<form action="index.php" id="plugin_form" class="multi_edit_form" method="post" name="longform">' . n . '<div class="txp-listtables">' . n . startTable('', '', 'txp-list') . n . '<thead>' . tr(n . hCell(fInput('checkbox', 'select_all', 0, '', '', '', '', '', 'select_all'), '', ' title="' . gTxt('toggle_all_selected') . '" class="multi-edit"') . n . column_head('plugin', 'name', 'plugin', true, $switch_dir, '', '', ('name' == $sort ? "{$dir} " : '') . 'name') . n . column_head('author', 'author', 'plugin', true, $switch_dir, '', '', ('author' == $sort ? "{$dir} " : '') . 'author') . n . column_head('version', 'version', 'plugin', true, $switch_dir, '', '', ('version' == $sort ? "{$dir} " : '') . 'version') . n . column_head('plugin_modified', 'modified', 'plugin', true, $switch_dir, '', '', ('modified' == $sort ? "{$dir} " : '') . 'modified') . n . hCell(gTxt('description'), '', ' class="description"') . n . column_head('active', 'status', 'plugin', true, $switch_dir, '', '', ('status' == $sort ? "{$dir} " : '') . 'status') . n . column_head('order', 'load_order', 'plugin', true, $switch_dir, '', '', ('load_order' == $sort ? "{$dir} " : '') . 'load-order') . n . hCell(gTxt('manage'), '', ' class="manage actions"')) . n . '</thead>'; echo '<tbody>'; while ($a = nextRow($rs)) { foreach ($a as $key => $value) { ${$key} = txpspecialchars($value); } // Fix up the description for clean cases $description = preg_replace(array('#<br />#', '#<(/?(a|b|i|em|strong))>#', '#<a href="(https?|\\.|\\/|ftp)([A-Za-z0-9:/?.=_]+?)">#'), array('<br />', '<$1>', '<a href="$1$2">'), $description); $help = !empty($help) ? '<a class="plugin-help" href="?event=plugin' . a . 'step=plugin_help' . a . 'name=' . urlencode($name) . '">' . gTxt('help') . '</a>' : ''; $plugin_prefs = $flags & PLUGIN_HAS_PREFS ? '<a class="plugin-prefs" href="?event=plugin_prefs.' . urlencode($name) . '">' . gTxt('plugin_prefs') . '</a>' : ''; $manage = array(); if ($help) { $manage[] = $help; } if ($plugin_prefs) { $manage[] = $plugin_prefs; } $manage_items = $manage ? join(tag(sp . '|' . sp, 'span'), $manage) : '-'; $edit_url = eLink('plugin', 'plugin_edit', 'name', $name, $name); echo tr(n . td(fInput('checkbox', 'selected[]', $name), '', 'multi-edit') . td($edit_url, '', 'name') . td(href($author, $author_uri, ' rel="external"'), '', 'author') . td($version, '', 'version') . td($modified ? '<span class="warning">' . gTxt('yes') . '</span>' : '', '', 'modified') . td($description, '', 'description') . td(status_link($status, $name, yes_no($status)), '', 'status') . td($load_order, '', 'load-order') . td($manage_items, '', 'manage'), $status ? ' class="active"' : ''); unset($name, $page, $deletelink); } echo '</tbody>', n, endTable(), n, '</div>', n, plugin_multiedit_form('', $sort, $dir, '', ''), n, tInput(), n, '</form>', n, '</div>'; // Show/hide "Options" link by setting the appropriate class on the plugins TR echo script_js(<<<EOS textpattern.Relay.register('txpAsyncHref.success', function(event, data) { \t\$(data['this']).closest('tr').toggleClass('active'); }); EOS ); } }
function cat_category_list($message = "") { pagetop(gTxt('categories'), $message); $out = array('<h1 class="txp-heading">' . gTxt('tab_organise') . '</h1>', '<div id="category_container" class="txp-container">', '<table class="category-list">', '<tr>', tdtl('<div id="categories_article">' . cat_article_list() . '</div>', ' class="categories article"'), tdtl('<div id="categories_link">' . cat_link_list() . '</div>', ' class="categories link"'), tdtl('<div id="categories_image">' . cat_image_list() . '</div>', ' class="categories image"'), tdtl('<div id="categories_file">' . cat_file_list() . '</div>', ' class="categories file"'), '</tr>', endTable(), '</div>', script_js(<<<EOS \t\t\t\$(document).ready(function() { \t\t\t\t\$('.category-tree').txpMultiEditForm({ \t\t\t\t\t'row' : 'p', \t\t\t\t\t'highlighted' : 'p' \t\t\t\t}); \t\t\t}); EOS )); echo join(n, $out); }
/** * Outputs the main panel listing all categories. * * @param string|array $message The activity message */ function cat_category_list($message = "") { pagetop(gTxt('categories'), $message); $out = array(hed(gTxt('tab_organise'), 1, 'class="txp-heading"'), n . tag(cat_article_list(), 'section', array('class' => 'txp-layout-4col-cell-1', 'id' => 'categories_article')), n . tag(cat_image_list(), 'section', array('class' => 'txp-layout-4col-cell-2', 'id' => 'categories_image')), n . tag(cat_file_list(), 'section', array('class' => 'txp-layout-4col-cell-3', 'id' => 'categories_file')), n . tag(cat_link_list(), 'section', array('class' => 'txp-layout-4col-cell-4', 'id' => 'categories_link')), script_js(<<<EOS \$(document).ready(function () { \$('.category-tree').txpMultiEditForm({ 'row' : 'p', 'highlighted' : 'p' }); }); EOS )); echo join(n, $out); }
/** * Outputs the main panel listing all categories. * * @param string|array $message The activity message */ function cat_category_list($message = "") { pagetop(gTxt('categories'), $message); $out = array(hed(gTxt('tab_organise'), 1, 'class="txp-heading"'), '<div id="category_container" class="txp-layout-grid">', n . tag(n . tag(cat_article_list(), 'div', array('class' => 'categories')), 'div', array('id' => 'categories_article', 'class' => 'txp-layout-cell txp-layout-1-4')), n . tag(n . tag(cat_image_list(), 'div', array('class' => 'categories')), 'div', array('id' => 'categories_image', 'class' => 'txp-layout-cell txp-layout-1-4')), n . tag(n . tag(cat_file_list(), 'div', array('class' => 'categories')), 'div', array('id' => 'categories_file', 'class' => 'txp-layout-cell txp-layout-1-4')), n . tag(n . tag(cat_link_list(), 'div', array('class' => 'categories')), 'div', array('id' => 'categories_link', 'class' => 'txp-layout-cell txp-layout-1-4')), '</div>', script_js(<<<EOS \$(document).ready(function () { \$('.category-tree').txpMultiEditForm({ 'row' : 'p', 'highlighted' : 'p' }); }); EOS )); echo join(n, $out); }
function form_list($curname) { global $step, $essential_forms, $form_types; $types = formTypes('', false); $methods = array('changetype' => array('label' => gTxt('changetype'), 'html' => $types), 'delete' => gTxt('delete')); $out[] = '<p class="action-create">' . sLink('form', 'form_create', gTxt('create_new_form')) . '</p>'; $criteria = 1; $criteria .= callback_event('admin_criteria', 'form_list', 0, $criteria); $rs = safe_rows_start("*", "txp_form", "{$criteria} order by field(type,'" . join("','", array_keys($form_types)) . "') asc, name asc"); if ($rs) { $ctr = 1; $prev_type = ''; while ($a = nextRow($rs)) { extract($a); $editlink = $curname != $name ? eLink('form', 'form_edit', 'name', $name, $name) : txpspecialchars($name); $modbox = !in_array($name, $essential_forms) ? '<input type="checkbox" name="selected_forms[]" value="' . $name . '" />' : ''; if ($prev_type != $type) { $visipref = 'pane_form_' . $type . '_visible'; $group_start = '<div class="form-list-group ' . $type . '"><h3 class="lever' . (get_pref($visipref) ? ' expanded' : '') . '"><a href="#' . $type . '">' . $form_types[$type] . '</a></h3>' . n . '<div id="' . $type . '" class="toggle form-list" style="display:' . (get_pref($visipref) ? 'block' : 'none') . '">' . n . '<ul class="plain-list">' . n; $group_end = $ctr > 1 ? '</ul></div></div>' . n : ''; } else { $group_start = $group_end = ''; } $out[] = $group_end . $group_start; $out[] = '<li>' . n . '<span class="form-list-action">' . $modbox . '</span><span class="form-list-name">' . $editlink . '</span></li>'; $prev_type = $type; $ctr++; } $out[] = '</ul></div></div>'; $out[] = multi_edit($methods, 'form', 'form_multi_edit'); return form(join('', $out), '', '', 'post', '', '', 'allforms_form') . script_js(<<<EOS \t\t\t\t\$(document).ready(function() { \t\t\t\t\t\$('#allforms_form').txpMultiEditForm({ \t\t\t\t\t\t'checkbox' : 'input[name="selected_forms[]"][type=checkbox]', \t\t\t\t\t\t'row' : '.plain-list li, .form-list-name', \t\t\t\t\t\t'highlighted' : '.plain-list li' \t\t\t\t\t}); \t\t\t\t}); EOS ); } }
function pagetop($pagetitle, $message = "") { global $siteurl, $sitename, $txp_user, $event, $step, $app_mode, $theme; if ($app_mode == 'async') { return; } $area = gps('area'); $event = !$event ? 'article' : $event; $bm = gps('bm'); $privs = safe_field("privs", "txp_users", "name = '" . doSlash($txp_user) . "'"); $GLOBALS['privs'] = $privs; $areas = areas(); $area = false; foreach ($areas as $k => $v) { if (in_array($event, $v)) { $area = $k; break; } } if (gps('logout')) { $body_id = 'page-logout'; } elseif (!$txp_user) { $body_id = 'page-login'; } else { $body_id = 'page-' . htmlspecialchars($event); } ?> <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd"> <html xmlns="http://www.w3.org/1999/xhtml" xml:lang="<?php echo LANG; ?> " lang="<?php echo LANG; ?> " dir="<?php echo gTxt('lang_dir'); ?> "> <head> <meta http-equiv="content-type" content="text/html; charset=utf-8" /> <meta name="robots" content="noindex, nofollow" /> <title>Txp › <?php echo htmlspecialchars($sitename); ?> › <?php echo escape_title($pagetitle); ?> </title> <script src="jquery.js" type="text/javascript"></script> <?php echo script_js('var textpattern = {event: "' . htmlspecialchars($event) . '", step: "' . htmlspecialchars($step) . '"};'); ?> <script type="text/javascript" src="textpattern.js"></script> <script type="text/javascript"> <!-- var cookieEnabled = checkCookies(); if (!cookieEnabled) { confirm('<?php echo trim(gTxt('cookies_must_be_enabled')); ?> '); } <?php $edit = array(); if ($event == 'list') { $rs = safe_column('name', 'txp_section', "name != 'default'"); $edit['section'] = $rs ? selectInput('Section', $rs, '', true) : ''; $rs = getTree('root', 'article'); $edit['category1'] = $rs ? treeSelectInput('Category1', $rs, '') : ''; $edit['category2'] = $rs ? treeSelectInput('Category2', $rs, '') : ''; $edit['comments'] = onoffRadio('Annotate', safe_field('val', 'txp_prefs', "name = 'comments_on_default'")); $edit['status'] = selectInput('Status', array(1 => gTxt('draft'), 2 => gTxt('hidden'), 3 => gTxt('pending'), 4 => gTxt('live'), 5 => gTxt('sticky')), '', true); $rs = safe_column('name', 'txp_users', "privs not in(0,6) order by name asc"); $edit['author'] = $rs ? selectInput('AuthorID', $rs, '', true) : ''; } if (in_array($event, array('image', 'file', 'link'))) { $rs = getTree('root', $event); $edit['category'] = $rs ? treeSelectInput('category', $rs, '') : ''; $rs = safe_column('name', 'txp_users', "privs not in(0,6) order by name asc"); $edit['author'] = $rs ? selectInput('author', $rs, '', true) : ''; } if ($event == 'plugin') { $edit['order'] = selectInput('order', array(1 => 1, 2 => 2, 3 => 3, 4 => 4, 5 => 5, 6 => 6, 7 => 7, 8 => 8, 9 => 9), 5, false); } if ($event == 'admin') { $edit['privilege'] = privs(); $rs = safe_column('name', 'txp_users', '1=1'); $edit_assign_assets = $rs ? selectInput('assign_assets', $rs, '', true) : ''; } // output JavaScript ?> function poweredit(elm) { var something = elm.options[elm.selectedIndex].value; // Add another chunk of HTML var pjs = document.getElementById('js'); if (pjs == null) { var br = document.createElement('br'); elm.parentNode.appendChild(br); pjs = document.createElement('P'); pjs.setAttribute('id','js'); elm.parentNode.appendChild(pjs); } if (pjs.style.display == 'none' || pjs.style.display == '') { pjs.style.display = 'block'; } if (something != '') { switch (something) { <?php foreach ($edit as $key => $val) { echo "case 'change" . $key . "':" . n . t . "pjs.innerHTML = '<span>" . str_replace(array("\n", '-'), array('', '-'), str_replace('</', '<\\/', addslashes($val))) . "<\\/span>';" . n . t . 'break;' . n . n; } if (isset($edit_assign_assets)) { echo "case 'delete':" . n . t . "pjs.innerHTML = '<label for=\"assign_assets\">" . addslashes(gTxt('assign_assets_to')) . "</label><span>" . str_replace(array("\n", '-'), array('', '-'), str_replace('</', '<\\/', addslashes($edit_assign_assets))) . "<\\/span>';" . n . t . 'break;' . n . n; } ?> default: pjs.style.display = 'none'; break; } } return false; } addEvent(window, 'load', cleanSelects); --> </script> <?php echo $theme->html_head(); callback_event('admin_side', 'head_end'); ?> </head> <body id="<?php echo $body_id; ?> " class="<?php echo $area; ?> "> <?php callback_event('admin_side', 'pagetop'); $theme->set_state($area, $event, $bm, $message); echo pluggable_ui('admin_side', 'header', $theme->header()); callback_event('admin_side', 'pagetop_end'); }
/** * Renders a HTML choice for whether Daylight Savings Time is in effect. * * Can be altered by plugins via the 'prefs_ui > is_dst' * pluggable UI callback event. * * @param string $name HTML name of the widget * @param string $val Initial (or current) selected item * @return string HTML */ function is_dst($name, $val) { $ui = yesnoRadio($name, $val) . script_js(<<<EOS \$(document).ready(function () { var radio = \$("#prefs-is_dst input"); if (radio) { if (\$("#auto_dst-1").prop("checked")) { radio.prop("disabled", "disabled"); } \$("#auto_dst-0").click(function () { radio.removeProp("disabled"); }); \$("#auto_dst-1").click(function () { radio.prop("disabled", "disabled"); }); } }); EOS ); return pluggable_ui('prefs_ui', 'is_dst', $ui, $name, $val); }
function pagetop($pagetitle, $message = "") { global $siteurl, $sitename, $txp_user, $event, $step, $app_mode, $theme; if ($app_mode == 'async') { return; } $area = gps('area'); $event = !$event ? 'article' : $event; $bm = gps('bm'); $privs = safe_field("privs", "txp_users", "name = '" . doSlash($txp_user) . "'"); $GLOBALS['privs'] = $privs; $areas = areas(); $area = false; foreach ($areas as $k => $v) { if (in_array($event, $v)) { $area = $k; break; } } if (gps('logout')) { $body_id = 'page-logout'; } elseif (!$txp_user) { $body_id = 'page-login'; } else { $body_id = 'page-' . txpspecialchars($event); } header('X-Frame-Options: ' . X_FRAME_OPTIONS); ?> <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd"> <html xmlns="http://www.w3.org/1999/xhtml" xml:lang="<?php echo LANG; ?> " lang="<?php echo LANG; ?> " dir="<?php echo txpspecialchars(gTxt('lang_dir')); ?> "> <head> <meta http-equiv="content-type" content="text/html; charset=utf-8" /> <meta name="robots" content="noindex, nofollow" /> <title><?php echo escape_title($pagetitle); ?> - <?php echo txpspecialchars($sitename); ?> | Textpattern CMS</title> <script type="text/javascript" src="jquery.js"></script> <?php echo script_js('var textpattern = { event: "' . txpspecialchars($event) . '", step: "' . txpspecialchars($step) . '", _txp_token: "' . txpspecialchars(form_token()) . '", ajax_timeout: ' . txpspecialchars(AJAX_TIMEOUT) . ', ajaxally_challenged: ' . (AJAXALLY_CHALLENGED ? 'true' : 'false') . ', textarray: {}, do_spellcheck: "' . txpspecialchars(get_pref('do_spellcheck', '#page-article #body, #page-article #title,' . '#page-image #alt-text, #page-image #caption,' . '#page-file #description,' . '#page-link #link-title, #page-link #link-description')) . '"};'); gTxtScript(array('form_submission_error', 'are_you_sure')); ?> <script type="text/javascript" src="textpattern.js"></script> <script type="text/javascript"> <!-- var cookieEnabled = checkCookies(); if (!cookieEnabled) { confirm('<?php echo trim(gTxt('cookies_must_be_enabled')); ?> '); } function poweredit(elm) { var something = elm.options[elm.selectedIndex].value; // Add another chunk of HTML var pjs = document.getElementById('js'); if (pjs == null) { var br = document.createElement('br'); elm.parentNode.appendChild(br); pjs = document.createElement('P'); pjs.setAttribute('id','js'); elm.parentNode.appendChild(pjs); } if (pjs.style.display == 'none' || pjs.style.display == '') { pjs.style.display = 'block'; } if (something != '') { switch (something) { default: pjs.style.display = 'none'; break; } } return false; } addEvent(window, 'load', cleanSelects); --> </script> <?php // Mandatory un-themable Textpattern core styles ?> <style type="text/css"> .not-ready .doc-ready, .not-ready form.async input[type="submit"], .not-ready a.async { visibility: hidden; } </style> <?php echo $theme->html_head(); callback_event('admin_side', 'head_end'); ?> </head> <body id="<?php echo $body_id; ?> " class="not-ready <?php echo $area; ?> "> <div class="txp-header"> <?php callback_event('admin_side', 'pagetop'); $theme->set_state($area, $event, $bm, $message); echo pluggable_ui('admin_side', 'header', $theme->header()); callback_event('admin_side', 'pagetop_end'); echo '</div><!-- /txp-header --><div class="txp-body">'; }
function doLoginForm($message) { include txpath . '/lib/txplib_head.php'; pagetop(gTxt('login'), $message); $stay = (cs('txp_login') and !gps('logout') ? 1 : 0); $reset = gps('reset'); $name = join(',', array_slice(explode(',', cs('txp_login')), 0, -1)); echo n . '<div id="login_container" class="txp-container">'; echo form('<div class="txp-login">' . n . hed(gTxt($reset ? 'password_reset' : 'login_to_textpattern'), 2) . n . graf('<span class="login-label"><label for="login_name">' . gTxt('name') . '</label></span>' . n . '<span class="login-value">' . fInput('text', 'p_userid', $name, '', '', '', INPUT_REGULAR, '', 'login_name') . '</span>', ' class="login-name"') . ($reset ? '' : n . graf('<span class="login-label"><label for="login_password">' . gTxt('password') . '</label></span>' . n . '<span class="login-value">' . fInput('password', 'p_password', '', '', '', '', INPUT_REGULAR, '', 'login_password') . '</span>', ' class="login-password"')) . ($reset ? '' : graf(checkbox('stay', 1, $stay, '', 'login_stay') . n . '<label for="login_stay">' . gTxt('stay_logged_in') . '</label>' . sp . popHelp('remember_login'), ' class="login-stay"')) . ($reset ? n . hInput('p_reset', 1) : '') . n . graf(fInput('submit', '', gTxt($reset ? 'password_reset_button' : 'log_in_button'), 'publish')) . n . ($reset ? graf('<a href="index.php">' . gTxt('back_to_login') . '</a>', ' class="login-return"') : graf('<a href="?reset=1">' . gTxt('password_forgotten') . '</a>', ' class="login-forgot"')) . (gps('event') ? eInput(gps('event')) : '') . '</div>', '', '', 'post', '', '', 'login_form') . '</div>' . n . script_js(<<<EOSCR // Focus on either username or password when empty \$(document).ready( \tfunction() { \t\tvar has_name = \$("#login_name").val().length; \t\tvar password_box = \$("#login_password").val(); \t\tvar has_password = (password_box) ? password_box.length : 0; \t\tif (!has_name) { \t\t\t\$("#login_name").focus(); \t\t} else if (!has_password) { \t\t \t\$("#login_password").focus(); \t\t} \t} ); EOSCR ) . n . '</div><!-- /txp-body -->' . n . '</body>' . n . '</html>'; exit(0); }
/** * Renders an admin-side search form. * * @param string $step Textpattern Step for the form submission * @param array $options Options * @return string HTML */ public function renderForm($step, $options = array()) { static $id_counter = 0; $event = $this->event; $methods = $this->getMethods(); $selected = $this->search_method; extract(lAtts(array('default_method' => 'all', 'submit_as' => 'get', 'placeholder' => '', 'label_all' => 'search_all', 'class' => ''), (array) $options)); $selected = $selected ? $selected : $default_method; $submit_as = in_array($submit_as, array('get', 'post')) ? $submit_as : 'get'; if (!is_array($selected)) { $selected = do_list($selected); } $set_all = count($selected) === 1 && $selected[0] === 'all' || count($selected) === count($methods); if ($label_all) { $methods = array('all' => gTxt($label_all)) + $methods; } $method_list = array(); foreach ($methods as $key => $value) { $name = $key === 'all' ? 'select_all' : 'search_method[]'; $method_list[] = tag(checkbox($name, $key, $set_all || in_array($key, $selected), 0, 'search-' . $key . $id_counter) . n . tag($value, 'label', array('for' => 'search-' . $key . $id_counter)) . n, 'li'); } $button_set = n . '<button class="txp-search-button">' . gTxt('search') . '</button>'; if (count($method_list) > 1) { $button_set .= n . '<button class="txp-search-options">' . gTxt('search_options') . '</button>' . n; } $buttons = n . tag($button_set, 'span', array('class' => 'txp-search-buttons')) . n; // So the search can be used multiple times on a page without id clashes. $id_counter++; // TODO: consider moving Route.add() to textpattern.js, but that involves adding one // call per panel that requires search, instead of auto-adding it when invoked here. return form(fInput('search', 'crit', $this->crit, 'txp-search-input', '', '', 24, 0, '', false, false, gTxt($placeholder)) . eInput($event) . sInput($step) . $buttons . n . tag(join(n, $method_list), 'ul', array('class' => 'txp-dropdown')), '', '', $submit_as, 'txp-search' . ($class ? ' ' . $class : ''), '', '', 'search') . script_js(<<<EOJS textpattern.Route.add('{$event}', txp_search); EOJS ); }
function article_edit($message = '', $concurrent = FALSE) { global $vars, $txp_user, $comments_disabled_after, $txpcfg, $prefs; extract($prefs); extract(gpsa(array('view', 'from_view', 'step'))); if (!empty($GLOBALS['ID'])) { // newly-saved article $ID = $GLOBALS['ID']; $step = 'edit'; } else { $ID = gps('ID'); } include_once txpath . '/lib/classTextile.php'; $textile = new Textile(); // switch to 'text' view upon page load and after article post if (!$view || gps('save') || gps('publish')) { $view = 'text'; } if (!$step) { $step = "create"; } if ($step == "edit" && $view == "text" && !empty($ID) && $from_view != 'preview' && $from_view != 'html' && !$concurrent) { $pull = true; //-- it's an existing article - off we go to the db $ID = assert_int($ID); $rs = safe_row("*, unix_timestamp(Posted) as sPosted,\n\t\t\t\tunix_timestamp(Expires) as sExpires,\n\t\t\t\tunix_timestamp(LastMod) as sLastMod", "textpattern", "ID={$ID}"); extract($rs); $reset_time = $publish_now = $Status < 4 && $sPosted <= time(); } else { $pull = false; //-- assume they came from post if ($from_view == 'preview' or $from_view == 'html') { $store_out = array(); $store = unserialize(base64_decode(ps('store'))); foreach ($vars as $var) { if (isset($store[$var])) { $store_out[$var] = $store[$var]; } } } else { $store_out = gpsa($vars); if ($concurrent) { $store_out['sLastMod'] = safe_field('unix_timestamp(LastMod) as sLastMod', 'textpattern', 'ID=' . $ID); } } $rs = $store_out; extract($store_out); } $GLOBALS['step'] = $step; if ($step == 'create') { $textile_body = $use_textile; $textile_excerpt = $use_textile; } if ($step != 'create') { // Previous record? $prev_id = checkIfNeighbour('prev', $sPosted); // Next record? $next_id = checkIfNeighbour('next', $sPosted); } $page_title = $Title ? $Title : gTxt('write'); pagetop($page_title, $message); echo n . n . '<form name="article" method="post" action="index.php">'; if (!empty($store_out)) { echo hInput('store', base64_encode(serialize($store_out))); } echo hInput('ID', $ID) . eInput('article') . sInput($step) . '<input type="hidden" name="view" />' . startTable('edit') . '<tr>' . n . '<td id="article-col-1">'; if ($view == 'text') { //-- markup help -------------- echo pluggable_ui('article_ui', 'sidehelp', side_help($textile_body, $textile_excerpt)); //-- custom menu entries -------------- echo pluggable_ui('article_ui', 'extend_col_1', '', $rs); //-- advanced -------------- echo '<h3 class="plain lever' . (get_pref('pane_article_advanced_visible') ? ' expanded' : '') . '"><a href="#advanced">' . gTxt('advanced_options') . '</a></h3>' . '<div id="advanced" class="toggle" style="display:' . (get_pref('pane_article_advanced_visible') ? 'block' : 'none') . '">'; // markup selection echo pluggable_ui('article_ui', 'markup', n . graf('<label for="markup-body">' . gTxt('article_markup') . '</label>' . br . pref_text('textile_body', $textile_body, 'markup-body')) . n . graf('<label for="markup-excerpt">' . gTxt('excerpt_markup') . '</label>' . br . pref_text('textile_excerpt', $textile_excerpt, 'markup-excerpt')), $rs); // form override echo $allow_form_override ? pluggable_ui('article_ui', 'override', graf('<label for="override-form">' . gTxt('override_default_form') . '</label>' . sp . popHelp('override_form') . br . form_pop($override_form, 'override-form')), $rs) : ''; // custom fields, believe it or not $max = get_pref('max_custom_fields', 10); $cf = ''; for ($i = 1; $i <= $max; $i++) { $custom_x_set = "custom_{$i}_set"; $custom_x = "custom_{$i}"; $cf .= ${$custom_x_set} !== '' ? custField($i, ${$custom_x_set}, ${$custom_x}) : ''; } echo pluggable_ui('article_ui', 'custom_fields', $cf, $rs); // keywords echo pluggable_ui('article_ui', 'keywords', n . graf('<label for="keywords">' . gTxt('keywords') . '</label>' . sp . popHelp('keywords') . br . n . '<textarea id="keywords" name="Keywords" cols="18" rows="5">' . htmlspecialchars(str_replace(',', ', ', $Keywords)) . '</textarea>'), $rs); // article image echo pluggable_ui('article_ui', 'article_image', n . graf('<label for="article-image">' . gTxt('article_image') . '</label>' . sp . popHelp('article_image') . br . fInput('text', 'Image', $Image, 'edit', '', '', 22, '', 'article-image')), $rs); // url title echo pluggable_ui('article_ui', 'url_title', n . graf('<label for="url-title">' . gTxt('url_title') . '</label>' . sp . popHelp('url_title') . br . fInput('text', 'url_title', $url_title, 'edit', '', '', 22, '', 'url-title')), $rs); echo '</div>' . n; //-- recent articles -------------- echo '<h3 class="plain lever' . (get_pref('pane_article_recent_visible') ? ' expanded' : '') . '"><a href="#recent">' . gTxt('recent_articles') . '</a>' . '</h3>' . '<div id="recent" class="toggle" style="display:' . (get_pref('pane_article_recent_visible') ? 'block' : 'none') . '">'; $recents = safe_rows_start("Title, ID", 'textpattern', "1=1 order by LastMod desc limit 10"); if ($recents) { echo '<ul class="plain-list">'; while ($recent = nextRow($recents)) { if (!$recent['Title']) { $recent['Title'] = gTxt('untitled') . sp . $recent['ID']; } echo n . t . '<li><a href="?event=article' . a . 'step=edit' . a . 'ID=' . $recent['ID'] . '">' . escape_title($recent['Title']) . '</a></li>'; } echo '</ul>'; } echo '</div>'; } else { echo sp; } echo '</td>' . n . '<td id="article-main">'; //-- title input -------------- if ($view == 'preview') { echo hed(gTxt('preview'), 2) . hed($Title, 1); } elseif ($view == 'html') { echo hed('XHTML', 2) . hed($Title, 1); } elseif ($view == 'text') { echo pluggable_ui('article_ui', 'title', n . '<p><label for="title">' . gTxt('title') . '</label>' . sp . popHelp('title') . br . '<input type="text" id="title" name="Title" value="' . escape_title($Title) . '" class="edit" size="40" tabindex="1" />', $rs); if ($step != 'create') { include_once txpath . '/publish/taghandlers.php'; $url = permlinkurl_id($ID); if ($Status != 4 and $Status != 5) { $url .= (strpos($url, '?') === FALSE ? '?' : '&') . 'txpreview=' . intval($ID) . '.' . time(); } echo sp . sp . '<a href="' . $url . '" class="article-view">' . gTxt('view') . '</a>'; } echo '</p>'; } //-- body -------------------- if ($view == 'preview') { if ($textile_body == USE_TEXTILE) { echo $textile->TextileThis($Body); } else { if ($textile_body == CONVERT_LINEBREAKS) { echo nl2br($Body); } else { if ($textile_body == LEAVE_TEXT_UNTOUCHED) { echo $Body; } } } } elseif ($view == 'html') { if ($textile_body == USE_TEXTILE) { $bod = $textile->TextileThis($Body); } else { if ($textile_body == CONVERT_LINEBREAKS) { $bod = nl2br($Body); } else { if ($textile_body == LEAVE_TEXT_UNTOUCHED) { $bod = $Body; } } } echo tag(str_replace(array(n, t), array(br, sp . sp . sp . sp), htmlspecialchars($bod)), 'code'); } else { echo pluggable_ui('article_ui', 'body', n . graf('<label for="body">' . gTxt('body') . '</label>' . sp . popHelp('body') . br . '<textarea id="body" name="Body" cols="55" rows="31" tabindex="2">' . htmlspecialchars($Body) . '</textarea>'), $rs); } //-- excerpt -------------------- if ($articles_use_excerpts) { if ($view == 'text') { echo pluggable_ui('article_ui', 'excerpt', n . graf('<label for="excerpt">' . gTxt('excerpt') . '</label>' . sp . popHelp('excerpt') . br . '<textarea id="excerpt" name="Excerpt" cols="55" rows="5" tabindex="3">' . htmlspecialchars($Excerpt) . '</textarea>'), $rs); } else { echo n . '<hr width="50%" />'; echo $textile_excerpt == USE_TEXTILE ? $view == 'preview' ? graf($textile->textileThis($Excerpt)) : tag(str_replace(array(n, t), array(br, sp . sp . sp . sp), htmlspecialchars($textile->TextileThis($Excerpt))), 'code') : graf($Excerpt); } } //-- author -------------- if ($view == "text" && $step != "create") { echo '<p class="small">' . gTxt('posted_by') . ': ' . htmlspecialchars($AuthorID) . ' · ' . safe_strftime('%d %b %Y · %X', $sPosted); if ($sPosted != $sLastMod) { echo br . gTxt('modified_by') . ': ' . htmlspecialchars($LastModID) . ' · ' . safe_strftime('%d %b %Y · %X', $sLastMod); } echo '</p>'; } echo hInput('from_view', $view), '</td>'; //-- layer tabs ------------------- echo '<td id="article-tabs">'; echo pluggable_ui('article_ui', 'view', $use_textile == USE_TEXTILE || $textile_body == USE_TEXTILE ? tag(tab('text', $view) . tab('html', $view) . tab('preview', $view), 'ul') : ' ', $rs); echo '</td>'; echo '<td id="article-col-2">'; if ($view == 'text') { if ($step != 'create') { echo n . graf(href(gtxt('create_new'), 'index.php?event=article')); } //-- prev/next article links -- if ($step != 'create' and ($prev_id or $next_id)) { echo '<p>', $prev_id ? prevnext_link('‹' . gTxt('prev'), 'article', 'edit', $prev_id, gTxt('prev')) : '', $next_id ? prevnext_link(gTxt('next') . '›', 'article', 'edit', $next_id, gTxt('next')) : '', '</p>'; } //-- status radios -------------- echo pluggable_ui('article_ui', 'status', n . n . '<fieldset id="write-status">' . n . '<legend>' . gTxt('status') . '</legend>' . n . status_radio($Status) . n . '</fieldset>', $rs); //-- category selects ----------- echo pluggable_ui('article_ui', 'categories', n . n . '<fieldset id="write-sort">' . n . '<legend>' . gTxt('sort_display') . '</legend>' . n . graf('<label for="category-1">' . gTxt('category1') . '</label> ' . '<span class="small">[' . eLink('category', '', '', '', gTxt('edit')) . ']</span>' . br . n . category_popup('Category1', $Category1, 'category-1')) . n . graf('<label for="category-2">' . gTxt('category2') . '</label>' . br . n . category_popup('Category2', $Category2, 'category-2')), $rs); //-- section select -------------- if (!$from_view && !$pull) { $Section = getDefaultSection(); } echo pluggable_ui('article_ui', 'section', n . graf('<label for="section">' . gTxt('section') . '</label> ' . '<span class="small">[' . eLink('section', '', '', '', gTxt('edit')) . ']</span>' . br . section_popup($Section, 'section')) . n . '</fieldset>', $rs); //-- "More" section echo n . n . '<h3 class="plain lever' . (get_pref('pane_article_more_visible') ? ' expanded' : '') . '"><a href="#more">' . gTxt('more') . '</a></h3>', '<div id="more" class="toggle" style="display:' . (get_pref('pane_article_more_visible') ? 'block' : 'none') . '">'; //-- comments stuff -------------- if ($step == "create") { //Avoiding invite disappear when previewing $AnnotateInvite = !empty($store_out['AnnotateInvite']) ? $store_out['AnnotateInvite'] : $comments_default_invite; if ($comments_on_default == 1) { $Annotate = 1; } } if ($use_comments == 1) { $invite[] = n . n . '<fieldset id="write-comments">' . n . '<legend>' . gTxt('comments') . '</legend>'; $comments_expired = false; if ($step != 'create' && $comments_disabled_after) { $lifespan = $comments_disabled_after * 86400; $time_since = time() - $sPosted; if ($time_since > $lifespan) { $comments_expired = true; } } if ($comments_expired) { $invite[] = n . n . graf(gTxt('expired')); } else { $invite[] = n . n . graf(onoffRadio('Annotate', $Annotate)) . n . n . graf('<label for="comment-invite">' . gTxt('comment_invitation') . '</label>' . br . fInput('text', 'AnnotateInvite', $AnnotateInvite, 'edit', '', '', '', '', 'comment-invite')); } $invite[] = n . n . '</fieldset>'; echo pluggable_ui('article_ui', 'annotate_invite', join('', $invite), $rs); } if ($step == "create" and empty($GLOBALS['ID'])) { //-- timestamp ------------------- //Avoiding modified date to disappear $persist_timestamp = !empty($store_out['year']) ? safe_strtotime($store_out['year'] . '-' . $store_out['month'] . '-' . $store_out['day'] . ' ' . $store_out['hour'] . ':' . $store_out['minute'] . ':' . $store_out['second']) : time(); echo pluggable_ui('article_ui', 'timestamp', n . n . '<fieldset id="write-timestamp">' . n . '<legend>' . gTxt('timestamp') . '</legend>' . n . graf(checkbox('publish_now', '1', $publish_now, '', 'publish_now') . '<label for="publish_now">' . gTxt('set_to_now') . '</label>') . n . graf(gTxt('or_publish_at') . sp . popHelp('timestamp')) . n . graf(gtxt('date') . sp . tsi('year', '%Y', $persist_timestamp) . ' / ' . tsi('month', '%m', $persist_timestamp) . ' / ' . tsi('day', '%d', $persist_timestamp)) . n . graf(gTxt('time') . sp . tsi('hour', '%H', $persist_timestamp) . ' : ' . tsi('minute', '%M', $persist_timestamp) . ' : ' . tsi('second', '%S', $persist_timestamp)) . n . '</fieldset>', array('sPosted' => $persist_timestamp) + $rs); //-- expires ------------------- $persist_timestamp = !empty($store_out['exp_year']) ? safe_strtotime($store_out['exp_year'] . '-' . $store_out['exp_month'] . '-' . $store_out['exp_day'] . ' ' . $store_out['exp_hour'] . ':' . $store_out['exp_minute'] . ':' . $store_out['second']) : NULLDATETIME; echo pluggable_ui('article_ui', 'expires', n . n . '<fieldset id="write-expires">' . n . '<legend>' . gTxt('expires') . '</legend>' . n . graf(gtxt('date') . sp . tsi('exp_year', '%Y', $persist_timestamp) . ' / ' . tsi('exp_month', '%m', $persist_timestamp) . ' / ' . tsi('exp_day', '%d', $persist_timestamp)) . n . graf(gTxt('time') . sp . tsi('exp_hour', '%H', $persist_timestamp) . ' : ' . tsi('exp_minute', '%M', $persist_timestamp) . ' : ' . tsi('exp_second', '%S', $persist_timestamp)) . n . '</fieldset>', $rs); // end "More" section echo n . n . '</div>'; //-- publish button -------------- echo has_privs('article.publish') ? fInput('submit', 'publish', gTxt('publish'), "publish", '', '', '', 4) : fInput('submit', 'publish', gTxt('save'), "publish", '', '', '', 4); } else { //-- timestamp ------------------- if (!empty($year)) { $sPosted = safe_strtotime($year . '-' . $month . '-' . $day . ' ' . $hour . ':' . $minute . ':' . $second); } echo pluggable_ui('article_ui', 'timestamp', n . n . '<fieldset id="write-timestamp">' . n . '<legend>' . gTxt('timestamp') . '</legend>' . n . graf(checkbox('reset_time', '1', $reset_time, '', 'reset_time') . '<label for="reset_time">' . gTxt('reset_time') . '</label>') . n . graf(gTxt('published_at') . sp . popHelp('timestamp')) . n . graf(gtxt('date') . sp . tsi('year', '%Y', $sPosted) . ' / ' . tsi('month', '%m', $sPosted) . ' / ' . tsi('day', '%d', $sPosted)) . n . graf(gTxt('time') . sp . tsi('hour', '%H', $sPosted) . ' : ' . tsi('minute', '%M', $sPosted) . ' : ' . tsi('second', '%S', $sPosted)) . n . hInput('sPosted', $sPosted) . n . hInput('sLastMod', $sLastMod) . n . hInput('AuthorID', $AuthorID) . n . hInput('LastModID', $LastModID) . n . '</fieldset>', $rs); //-- expires ------------------- if (!empty($exp_year)) { if (empty($exp_month)) { $exp_month = 1; } if (empty($exp_day)) { $exp_day = 1; } if (empty($exp_hour)) { $exp_hour = 0; } if (empty($exp_minute)) { $exp_minute = 0; } if (empty($exp_second)) { $exp_second = 0; } $sExpires = safe_strtotime($exp_year . '-' . $exp_month . '-' . $exp_day . ' ' . $exp_hour . ':' . $exp_minute . ':' . $exp_second); } echo pluggable_ui('article_ui', 'expires', n . n . '<fieldset id="write-expires">' . n . '<legend>' . gTxt('expires') . '</legend>' . n . graf(gtxt('date') . sp . tsi('exp_year', '%Y', $sExpires) . ' / ' . tsi('exp_month', '%m', $sExpires) . ' / ' . tsi('exp_day', '%d', $sExpires)) . n . graf(gTxt('time') . sp . tsi('exp_hour', '%H', $sExpires) . ' : ' . tsi('exp_minute', '%M', $sExpires) . ' : ' . tsi('exp_second', '%S', $sExpires)) . n . hInput('sExpires', $sExpires) . n . '</fieldset>', $rs); // end "More" section echo n . n . '</div>'; //-- save button -------------- if ($Status >= 4 and has_privs('article.edit.published') or $Status >= 4 and $AuthorID == $txp_user and has_privs('article.edit.own.published') or $Status < 4 and has_privs('article.edit') or $Status < 4 and $AuthorID == $txp_user and has_privs('article.edit.own')) { echo fInput('submit', 'save', gTxt('save'), "publish", '', '', '', 4); } } } echo '</td></tr></table></form>' . n; // Assume users would not change the timestamp if they wanted to "publish now"/"reset time" echo script_js(<<<EOS \t\t\$('#write-timestamp input.edit').change( \t\t\tfunction() { \t\t\t\t\$('#publish_now').attr('checked', false); \t\t\t\t\$('#reset_time').attr('checked', false); \t\t\t}); EOS ); }
if (!defined('txpinterface')) { die('txpinterface is undefined.'); } // ------------------------------------------------------------- ?> <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd"> <html xmlns="http://www.w3.org/1999/xhtml" xml:lang="en" lang="en"> <head> <meta http-equiv="Content-Type" content="text/html; charset=utf-8" /> <title>Txp › <?php echo gTxt('build'); ?> </title> <script type="text/javascript" src="jquery.js"></script> <?php echo script_js("var textpattern = {event: '{$event}', step: '{$step}'};"); ?> <?php echo $theme->html_head(); ?> </head> <body id="tag-event"> <?php $tag_name = gps('tag_name'); $functname = 'tag_' . $tag_name; if (function_exists($functname)) { $endform = n . tr(td() . td(fInput('submit', '', gTxt('build'), 'smallerbox'))) . n . endTable() . n . eInput('tag') . n . sInput('build') . n . hInput('tag_name', $tag_name); echo $functname($tag_name); } ?>
/** * Creates and outputs an admin-side header. * * The output contains HTML <head> section and the main * navigation. The results are echoed as opposed to returned. * * This function offers a way to invoke modal activity messages * and set the page title. * * Output will automatically become silent on asynchronous * script responses that do not want HTML headers. * * @param string $pagetitle The page title * @param string|array $message A message show to the user * @example * pagetop('Title', array('My error message', E_ERROR)); * echo 'My page contents.'; */ function pagetop($pagetitle, $message = '') { global $siteurl, $sitename, $txp_user, $event, $step, $app_mode, $theme, $privs; if ($app_mode == 'async') { return; } $area = gps('area'); $event = !$event ? 'article' : $event; $bm = gps('bm'); $privs = safe_field("privs", "txp_users", "name = '" . doSlash($txp_user) . "'"); $areas = areas(); $area = false; foreach ($areas as $k => $v) { if (in_array($event, $v)) { $area = $k; break; } } if (gps('logout')) { $body_id = 'page-logout'; } elseif (!$txp_user) { $body_id = 'page-login'; } else { $body_id = 'page-' . txpspecialchars($event); } header('X-Frame-Options: ' . X_FRAME_OPTIONS); header('X-UA-Compatible: ' . X_UA_COMPATIBLE); $lang_direction = gTxt('lang_dir'); if (!in_array($lang_direction, array('ltr', 'rtl'))) { // Apply biased default for missing translations $lang_direction = 'ltr'; } ?> <!DOCTYPE html> <html lang="<?php echo LANG; ?> " dir="<?php echo $lang_direction; ?> "> <head> <meta charset="utf-8"> <meta name="robots" content="noindex, nofollow"> <title><?php echo admin_title($pagetitle); ?> </title><?php echo script_js('vendors/jquery/jquery/jquery.js', TEXTPATTERN_SCRIPT_URL) . script_js('vendors/jquery/ui/js/jquery-ui.js', TEXTPATTERN_SCRIPT_URL) . script_js('//code.jquery.com/jquery-migrate-1.2.1.js', TEXTPATTERN_SCRIPT_URL) . script_js('var textpattern = ' . json_encode(array('event' => $event, 'step' => $step, '_txp_token' => form_token(), 'ajax_timeout' => (int) AJAX_TIMEOUT, 'textarray' => (object) null, 'do_spellcheck' => get_pref('do_spellcheck', '#page-article #body, #page-article #title,' . '#page-image #alt-text, #page-image #caption,' . '#page-file #description,' . '#page-link #link-title, #page-link #link-description'), 'production_status' => get_pref('production_status'))) . ';') . script_js('textpattern.js', TEXTPATTERN_SCRIPT_URL) . n; gTxtScript(array('form_submission_error', 'are_you_sure', 'cookies_must_be_enabled', 'ok', 'save', 'publish')); // Mandatory un-themable Textpattern core styles ?> <style> .not-ready .doc-ready, .not-ready form.async input[type="submit"], .not-ready a.async { visibility: hidden; } </style> <?php echo $theme->html_head(); callback_event('admin_side', 'head_end'); ?> </head> <body id="<?php echo $body_id; ?> " class="not-ready <?php echo $area; ?> "> <header role="banner" class="txp-header"> <?php callback_event('admin_side', 'pagetop'); $theme->set_state($area, $event, $bm, $message); echo pluggable_ui('admin_side', 'header', $theme->header()); callback_event('admin_side', 'pagetop_end'); echo n . '</header><!-- /txp-header -->' . n . '<main role="main" class="txp-body" aria-label="' . gTxt('main_content') . '">'; callback_event('admin_side', 'main_content'); }
} global $textarray_script; $step = ps('step'); $rel_siteurl = preg_replace("#^(.*?)({$txpdir})?/setup.*\$#i", '$1', $_SERVER['PHP_SELF']); $rel_txpurl = rtrim(dirname(dirname($_SERVER['PHP_SELF'])), '/\\'); $bodyclass = $step == '' ? ' welcome' : ''; gTxtScript(array('setup_password_strength_0', 'setup_password_strength_1', 'setup_password_strength_2', 'setup_password_strength_3', 'setup_password_strength_4')); echo <<<eod <!DOCTYPE html> <html lang="en"> <head> <meta charset="utf-8"> <meta name="robots" content="noindex, nofollow"> <title>Setup | Textpattern CMS</title> eod; echo script_js('../vendors/jquery/jquery/jquery.js', TEXTPATTERN_SCRIPT_URL) . script_js('../vendors/jquery/jquery-ui/jquery-ui.js', TEXTPATTERN_SCRIPT_URL) . script_js('../vendors/dropbox/zxcvbn/zxcvbn.js', TEXTPATTERN_SCRIPT_URL) . script_js('var textpattern = ' . json_encode(array('event' => 'setup', 'step' => $step, 'textarray' => (object) $textarray_script)) . ';') . script_js('../textpattern.js', TEXTPATTERN_SCRIPT_URL); echo <<<eod <link rel="stylesheet" href="../theme/hive/assets/css/textpattern.min.css"> <meta name="viewport" content="width=device-width, initial-scale=1, maximum-scale=1, user-scalable=0"> </head> <body class="setup{$bodyclass}" id="page-setup"> <main class="txp-body"> eod; switch ($step) { case '': chooseLang(); break; case 'getDbInfo': getDbInfo(); break; case 'getTxpLogin':
private function _announce($thing, $async, $modal) { // $thing[0]: message text. // $thing[1]: message type, defaults to "success" unless empty or a different flag is set. if ($thing === '') { return ''; } if (!is_array($thing) || !isset($thing[1])) { $thing = array($thing, 0); } switch ($thing[1]) { case E_ERROR: $class = 'error'; $icon = 'ui-icon-closethick'; break; case E_WARNING: $class = 'warning'; $icon = 'ui-icon-alert'; break; default: $class = 'success'; $icon = 'ui-icon-check'; break; } if ($modal) { $html = ''; // TODO: Say what? $js = 'window.alert("' . escape_js(strip_tags($thing[0])) . '")'; } else { $html = span(span(null, array('class' => 'ui-icon ' . $icon)) . ' ' . gTxt($thing[0]) . sp . href('×', '#close', ' class="close" role="button" title="' . gTxt('close') . '" aria-label="' . gTxt('close') . '"'), array('class' => 'messageflash ' . $class, 'role' => 'alert', 'aria-live' => 'assertive')); // Try to inject $html into the message pane no matter when _announce()'s output is printed. $js = escape_js($html); $js = <<<EOS \$(document).ready(function () { \$("#messagepane").html("{$js}"); \$(window).resize(function () { \$("#messagepane").css({ left: (\$(window).width() - \$("#messagepane").outerWidth()) / 2 }); }); \$(window).resize(); }); EOS; } if ($async) { return $js; } else { return script_js(str_replace('</', '<\\/', $js), $html); } }
" lang="<?php echo LANG; ?> " dir="<?php echo txpspecialchars(gTxt('lang_dir')); ?> "> <head> <meta http-equiv="Content-Type" content="text/html; charset=utf-8" /> <title><?php echo gTxt('build'); ?> | Textpattern CMS</title> <script type="text/javascript" src="jquery.js"></script> <?php echo script_js('var textpattern = {event: "' . txpspecialchars($event) . '", step: "' . txpspecialchars($step) . '", _txp_token: "' . txpspecialchars(form_token()) . '"};'); ?> <?php echo $theme->html_head(); ?> </head> <body id="tag-event"> <?php $tag_name = gps('tag_name'); $functname = 'tag_' . $tag_name; if (function_exists($functname)) { $endform = n . tr(td() . td(fInput('submit', '', gTxt('build')))) . n . endTable() . n . eInput('tag') . n . sInput('build') . n . hInput('tag_name', $tag_name); echo $functname($tag_name); } ?>
/** * Renders a checkbox to set/unset a browser cookie. * * @param string $classname Label text. The cookie's name will be derived from this value * @param bool $form Create as a stand-along <form> element * @return string HTML */ function cookie_box($classname, $form = true) { $name = 'cb_' . $classname; $id = escape_js($name); $class = escape_js($classname); if (cs('toggle_' . $classname)) { $value = 1; } else { $value = 0; } $newvalue = 1 - $value; $out = checkbox($name, 1, (bool) $value, 0, $name) . n . tag(gTxt($classname), 'label', array('for' => $name)); $js = <<<EOF \$(function () { \$('input') .filter(function () { if (\$(this).attr('id') === '{$id}') { return true; } }) .change(function () { setClassRemember('{$class}', {$newvalue}); \$(this).parents('form').submit(); }); }); EOF; $out .= script_js($js); if ($form) { if (serverSet('QUERY_STRING')) { $action = 'index.php?' . serverSet('QUERY_STRING'); } else { $action = 'index.php'; } $out .= eInput(gps('event')) . tInput(); return tag($out, 'form', array('class' => $name, 'method' => 'post', 'action' => $action)); } return $out; }
?> <!DOCTYPE html> <html lang="<?php echo LANG; ?> " dir="<?php echo txpspecialchars(gTxt('lang_dir')); ?> "> <head> <meta charset="utf-8"> <title><?php echo gTxt('build'); ?> | Textpattern CMS</title><?php echo script_js('vendors/jquery/jquery/jquery.js', TEXTPATTERN_SCRIPT_URL) . script_js('vendors/jquery/ui/js/jquery-ui.js', TEXTPATTERN_SCRIPT_URL) . script_js('//code.jquery.com/jquery-migrate-1.2.1.js', TEXTPATTERN_SCRIPT_URL) . script_js('var textpattern = ' . json_encode(array('event' => $event, 'step' => $step, '_txp_token' => form_token(), 'textarray' => (object) null)) . ';') . script_js('textpattern.js', TEXTPATTERN_SCRIPT_URL) . n; // Mandatory un-themable Textpattern core styles echo $theme->html_head(); ?> </head> <body id="tag-event"> <?php echo Txp::get('Textpattern_Tag_BuilderTags')->renderTagHelp(gps('tag_name')); ?> </body> </html> <?php /** * Collection of tag builder functions. * * @package Admin\Tag
function sec_section_list($message = '') { global $event, $section_list_pageby; pagetop(gTxt('tab_sections'), $message); extract(gpsa(array('page', 'sort', 'dir', 'crit', 'search_method'))); if ($sort === '') { $sort = get_pref('section_sort_column', 'time'); } if ($dir === '') { $dir = get_pref('section_sort_dir', 'desc'); } $dir = $dir == 'asc' ? 'asc' : 'desc'; switch ($sort) { case 'title': $sort_sql = 'title ' . $dir; break; case 'page': $sort_sql = 'page ' . $dir; break; case 'css': $sort_sql = 'css ' . $dir; break; case 'in_rss': $sort_sql = 'in_rss ' . $dir; break; case 'on_frontpage': $sort_sql = 'on_frontpage ' . $dir; break; case 'searchable': $sort_sql = 'searchable ' . $dir; break; case 'article_count': $sort_sql = 'article_count ' . $dir; break; default: $sort_sql = 'name ' . $dir; break; } set_pref('section_sort_column', $sort, 'section', 2, '', 0, PREF_PRIVATE); set_pref('section_sort_dir', $dir, 'section', 2, '', 0, PREF_PRIVATE); $switch_dir = $dir == 'desc' ? 'asc' : 'desc'; $criteria = 1; if ($search_method and $crit != '') { $verbatim = preg_match('/^"(.*)"$/', $crit, $m); $crit_escaped = doSlash($verbatim ? $m[1] : str_replace(array('\\', '%', '_', '\''), array('\\\\', '\\%', '\\_', '\\\''), $crit)); $critsql = $verbatim ? array('name' => "name = '{$crit_escaped}'", 'title' => "title = '{$crit_escaped}'", 'page' => "page = '{$crit_escaped}'", 'css' => "css = '{$crit_escaped}'", 'in_rss' => "in_rss = '{$crit_escaped}'", 'on_frontpage' => "on_frontpage = '{$crit_escaped}'", 'searchable' => "searchable = '{$crit_escaped}'") : array('name' => "name like '%{$crit_escaped}%'", 'title' => "title like '%{$crit_escaped}%'", 'page' => "page like '%{$crit_escaped}%'", 'css' => "css like '%{$crit_escaped}%'", 'in_rss' => "in_rss = '{$crit_escaped}'", 'on_frontpage' => "on_frontpage = '{$crit_escaped}'", 'searchable' => "searchable = '{$crit_escaped}'"); if (array_key_exists($search_method, $critsql)) { $criteria = $critsql[$search_method]; $limit = 500; } else { $search_method = ''; $crit = ''; } } else { $search_method = ''; $crit = ''; } $criteria .= callback_event('admin_criteria', 'section_list', 0, $criteria); $total = safe_count('txp_section', "{$criteria}"); echo '<h1 class="txp-heading">' . gTxt('tab_sections') . sp . popHelp('section_category') . '</h1>'; echo '<div id="' . $event . '_control" class="txp-control-panel">'; echo graf(sLink('section', 'section_edit', gTxt('create_section')), ' class="txp-buttons"'); echo n . '<form id="default_section_form" name="default_section_form" method="post" action="index.php" class="async">'; echo graf('<label>' . gTxt('default_write_section') . '</label>' . sp . popHelp('section_default') . n . section_select_list()) . eInput('section') . sInput('section_set_default'); echo '</form>'; if ($total < 1) { if ($criteria != 1) { echo n . section_search_form($crit, $search_method) . n . graf(gTxt('no_results_found'), ' class="indicator"') . '</div>'; } return; } $limit = max($section_list_pageby, 15); list($page, $offset, $numPages) = pager($total, $limit, $page); echo n . section_search_form($crit, $search_method) . '</div>'; $rs = safe_rows_start('*, (SELECT count(*) FROM ' . safe_pfx('textpattern') . ' articles WHERE articles.Section = txp_section.name) AS article_count', 'txp_section', "{$criteria} order by {$sort_sql} limit {$offset}, {$limit}"); if ($rs) { echo n . '<div id="' . $event . '_container" class="txp-container">'; echo n . n . '<form action="index.php" id="section_form" class="multi_edit_form" method="post" name="longform">' . n . '<div class="txp-listtables">' . n . n . startTable('', '', 'txp-list') . n . '<thead>' . n . tr(n . hCell(fInput('checkbox', 'select_all', 0, '', '', '', '', '', 'select_all'), '', ' title="' . gTxt('toggle_all_selected') . '" class="multi-edit"') . n . column_head('name', 'name', 'section', true, $switch_dir, $crit, $search_method, ('name' == $sort ? "{$dir} " : '') . 'name') . n . column_head('title', 'title', 'section', true, $switch_dir, $crit, $search_method, ('title' == $sort ? "{$dir} " : '') . 'title') . n . column_head('page', 'page', 'section', true, $switch_dir, $crit, $search_method, ('page' == $sort ? "{$dir} " : '') . 'page') . n . column_head('css', 'css', 'section', true, $switch_dir, $crit, $search_method, ('css' == $sort ? "{$dir} " : '') . 'style') . n . column_head('on_front_page', 'on_frontpage', 'section', true, $switch_dir, $crit, $search_method, ('on_frontpage' == $sort ? "{$dir} " : '') . 'section_detail frontpage') . n . column_head('syndicate', 'in_rss', 'section', true, $switch_dir, $crit, $search_method, ('in_rss' == $sort ? "{$dir} " : '') . 'section_detail syndicate') . n . column_head('include_in_search', 'searchable', 'section', true, $switch_dir, $crit, $search_method, ('searchable' == $sort ? "{$dir} " : '') . 'section_detail searchable') . n . column_head('articles', 'article_count', 'section', true, $switch_dir, $crit, $search_method, ('article_count' == $sort ? "{$dir} " : '') . 'section_detail article_count')) . n . '</thead>'; echo '<tbody>'; while ($a = nextRow($rs)) { extract($a, EXTR_PREFIX_ALL, 'sec'); $is_default_section = $sec_name == 'default'; $edit_url = '?event=section' . a . 'step=section_edit' . a . 'name=' . $sec_name . a . 'sort=' . $sort . a . 'dir=' . $dir . a . 'page=' . $page . a . 'search_method=' . $search_method . a . 'crit=' . $crit; $page_url = '?event=page' . a . 'name=' . $sec_page; $style_url = '?event=css' . a . 'name=' . $sec_css; $articles = $sec_article_count > 0 ? href($sec_article_count, '?event=list' . a . 'search_method=section' . a . 'crit="' . txpspecialchars($sec_name) . '"', ' title="' . gTxt('article_count', array('{num}' => $sec_article_count)) . '"') : ($is_default_section ? '' : '0'); // $can_delete = ($sec_name != 'default' && $sec_article_count == 0); $parms = array('step' => 'section_toggle_option', 'thing' => $sec_name); echo tr(td(fInput('checkbox', 'selected[]', $sec_name), '', 'multi-edit') . td('<a href="' . $edit_url . '" title="' . gTxt('edit') . '">' . $sec_name . '</a>' . n . '<span class="section_detail">[<a href="' . hu . $sec_name . '">' . gTxt('view') . '</a>]</span>', '', 'name') . td(txpspecialchars($sec_title), '', 'title') . td('<a href="' . $page_url . '" title="' . gTxt('edit') . '">' . $sec_page . '</a>', '', 'page') . td('<a href="' . $style_url . '" title="' . gTxt('edit') . '">' . $sec_css . '</a>', '', 'style') . td($is_default_section ? '-' : asyncHref($sec_on_frontpage ? gTxt('yes') : gTxt('no'), $parms + array('property' => 'on_frontpage')), '', 'section_detail frontpage') . td($is_default_section ? '-' : asyncHref($sec_in_rss ? gTxt('yes') : gTxt('no'), $parms + array('property' => 'in_rss')), '', 'section_detail syndicate') . td($is_default_section ? '-' : asyncHref($sec_searchable ? gTxt('yes') : gTxt('no'), $parms + array('property' => 'searchable')), '', 'section_detail searchable') . td($is_default_section ? '' : $articles, '', 'section_detail article_count'), ' id="txp_section_' . $sec_name . '"'); } echo '</tbody>', n, endTable(), n, '</div>', n, section_multiedit_form($page, $sort, $dir, $crit, $search_method), n, tInput(), n, '</form>', n, graf(toggle_box('section_detail'), ' class="detail-toggle"'), n, '<div id="' . $event . '_navigation" class="txp-navigation">', n, nav_form('section', $page, $numPages, $sort, $dir, $crit, $search_method, $total, $limit), n, pageby_form('section', $section_list_pageby), n, '</div>', n, '</div>'; echo script_js(<<<EOS \t\t\t\$('#default_section').change(function() { \t\t\t\t\$('#default_section_form').submit(); \t\t\t}); EOS ); } }
function article_edit($message = '', $concurrent = FALSE, $refresh_partials = FALSE) { global $vars, $txp_user, $prefs, $event; extract($prefs); /* $partials is an array of: $key => array ( 'mode' => {PARTIAL_STATIC | PARTIAL_VOLATILE | PARTIAL_VOLATILE_VALUE}, 'selector' => $DOM_selector, 'cb' => $callback_function, 'html' => $return_value_of_callback_function (need not be intialized here) ) */ $partials = array('sLastMod' => array('mode' => PARTIAL_VOLATILE_VALUE, 'selector' => '[name=sLastMod]', 'cb' => 'article_partial_value'), 'sPosted' => array('mode' => PARTIAL_VOLATILE_VALUE, 'selector' => '[name=sPosted]', 'cb' => 'article_partial_value'), 'custom_fields' => array('mode' => PARTIAL_STATIC, 'selector' => '#custom_field_group', 'cb' => 'article_partial_custom_fields'), 'image' => array('mode' => PARTIAL_STATIC, 'selector' => '#image_group', 'cb' => 'article_partial_image'), 'keywords' => array('mode' => PARTIAL_STATIC, 'selector' => 'p.keywords', 'cb' => 'article_partial_keywords'), 'keywords_value' => array('mode' => PARTIAL_VOLATILE_VALUE, 'selector' => '#keywords', 'cb' => 'article_partial_keywords_value'), 'url_title' => array('mode' => PARTIAL_STATIC, 'selector' => 'p.url-title', 'cb' => 'article_partial_url_title'), 'url_title_value' => array('mode' => PARTIAL_VOLATILE_VALUE, 'selector' => '#url-title', 'cb' => 'article_partial_url_title_value'), 'recent_articles' => array('mode' => PARTIAL_VOLATILE, 'selector' => '#recent_group .recent', 'cb' => 'article_partial_recent_articles'), 'title' => array('mode' => PARTIAL_STATIC, 'selector' => 'p.title', 'cb' => 'article_partial_title'), 'title_value' => array('mode' => PARTIAL_VOLATILE_VALUE, 'selector' => '#title', 'cb' => 'article_partial_title_value'), 'article_view' => array('mode' => PARTIAL_VOLATILE, 'selector' => '#article_partial_article_view', 'cb' => 'article_partial_article_view'), 'body' => array('mode' => PARTIAL_STATIC, 'selector' => 'p.body', 'cb' => 'article_partial_body'), 'excerpt' => array('mode' => PARTIAL_STATIC, 'selector' => 'p.excerpt', 'cb' => 'article_partial_excerpt'), 'author' => array('mode' => PARTIAL_VOLATILE, 'selector' => 'p.author', 'cb' => 'article_partial_author'), 'article_nav' => array('mode' => PARTIAL_VOLATILE, 'selector' => 'p.nav-tertiary', 'cb' => 'article_partial_article_nav'), 'status' => array('mode' => PARTIAL_VOLATILE, 'selector' => '#write-status', 'cb' => 'article_partial_status'), 'categories' => array('mode' => PARTIAL_STATIC, 'selector' => '#categories_group', 'cb' => 'article_partial_categories'), 'section' => array('mode' => PARTIAL_STATIC, 'selector' => 'p.section', 'cb' => 'article_partial_section'), 'comments' => array('mode' => PARTIAL_VOLATILE, 'selector' => '#write-comments', 'cb' => 'article_partial_comments'), 'posted' => array('mode' => PARTIAL_VOLATILE, 'selector' => '#write-timestamp', 'cb' => 'article_partial_posted'), 'expires' => array('mode' => PARTIAL_VOLATILE, 'selector' => '#write-expires', 'cb' => 'article_partial_expires')); // add partials for custom fields (and their values which is redundant by design, for plugins) global $cfs; foreach ($cfs as $k => $v) { $partials["custom_field_{$k}"] = array('mode' => PARTIAL_STATIC, 'selector' => "p.custom-field.custom-{$k}", 'cb' => 'article_partial_custom_field'); $partials["custom_{$k}"] = array('mode' => PARTIAL_STATIC, 'selector' => "#custom-{$k}", 'cb' => 'article_partial_value'); } extract(gpsa(array('view', 'from_view', 'step'))); if (!empty($GLOBALS['ID'])) { // newly-saved article $ID = $GLOBALS['ID']; $step = 'edit'; } else { $ID = gps('ID'); } // switch to 'text' view upon page load and after article post if (!$view || gps('save') || gps('publish')) { $view = 'text'; } if (!$step) { $step = "create"; } if ($step == "edit" && $view == "text" && !empty($ID) && $from_view != 'preview' && $from_view != 'html' && !$concurrent) { $pull = true; //-- it's an existing article - off we go to the db $ID = assert_int($ID); $rs = safe_row("*, unix_timestamp(Posted) as sPosted,\n\t\t\t\tunix_timestamp(Expires) as sExpires,\n\t\t\t\tunix_timestamp(LastMod) as sLastMod", "textpattern", "ID={$ID}"); if (empty($rs)) { return; } $rs['reset_time'] = $rs['publish_now'] = false; } else { $pull = false; //-- assume they came from post if ($from_view == 'preview' or $from_view == 'html') { $store_out = array(); $store = unserialize(base64_decode(ps('store'))); foreach ($vars as $var) { if (isset($store[$var])) { $store_out[$var] = $store[$var]; } } } else { $store_out = gpsa($vars); if ($concurrent) { $store_out['sLastMod'] = safe_field('unix_timestamp(LastMod) as sLastMod', 'textpattern', 'ID=' . $ID); } } $rs = textile_main_fields($store_out); if (!empty($rs['exp_year'])) { if (empty($rs['exp_month'])) { $rs['exp_month'] = 1; } if (empty($rs['exp_day'])) { $rs['exp_day'] = 1; } if (empty($rs['exp_hour'])) { $rs['exp_hour'] = 0; } if (empty($rs['exp_minute'])) { $rs['exp_minute'] = 0; } if (empty($rs['exp_second'])) { $rs['exp_second'] = 0; } $rs['sExpires'] = safe_strtotime($rs['exp_year'] . '-' . $rs['exp_month'] . '-' . $rs['exp_day'] . ' ' . $rs['exp_hour'] . ':' . $rs['exp_minute'] . ':' . $rs['exp_second']); } if (!empty($rs['year'])) { $rs['sPosted'] = safe_strtotime($rs['year'] . '-' . $rs['month'] . '-' . $rs['day'] . ' ' . $rs['hour'] . ':' . $rs['minute'] . ':' . $rs['second']); } } $validator = new Validator(array(new SectionConstraint($rs['Section']))); if (!$validator->validate()) { $rs['Section'] = getDefaultSection(); } extract($rs); $GLOBALS['step'] = $step; if ($step == 'create') { $textile_body = $use_textile; $textile_excerpt = $use_textile; } if ($step != 'create' && isset($sPosted)) { // Previous record? $rs['prev_id'] = checkIfNeighbour('prev', $sPosted); // Next record? $rs['next_id'] = checkIfNeighbour('next', $sPosted); } else { $rs['prev_id'] = $rs['next_id'] = 0; } // let plugins chime in on partials meta data callback_event_ref('article_ui', 'partials_meta', 0, $rs, $partials); $rs['partials_meta'] =& $partials; // get content for volatile partials foreach ($partials as $k => $p) { if ($p['mode'] == PARTIAL_VOLATILE || $p['mode'] == PARTIAL_VOLATILE_VALUE) { $cb = $p['cb']; $partials[$k]['html'] = is_array($cb) ? call_user_func($cb, $rs, $k) : $cb($rs, $k); } } if ($refresh_partials) { global $theme; $response[] = $theme->announce_async($message); // update the volatile partials foreach ($partials as $k => $p) { // volatile partials need a target DOM selector if (empty($p['selector']) && $p['mode'] != PARTIAL_STATIC) { trigger_error("Empty selector for partial '{$k}'", E_USER_ERROR); } else { // build response script if ($p['mode'] == PARTIAL_VOLATILE) { // volatile partials replace *all* of the existing HTML fragment for their selector $response[] = '$("' . $p['selector'] . '").replaceWith("' . escape_js($p['html']) . '")'; } elseif ($p['mode'] == PARTIAL_VOLATILE_VALUE) { // volatile partial values replace the *value* of elements matching their selector $response[] = '$("' . $p['selector'] . '").val("' . escape_js($p['html']) . '")'; } } } send_script_response(join(";\n", $response)); // bail out return; } foreach ($partials as $k => $p) { if ($p['mode'] == PARTIAL_STATIC) { $cb = $p['cb']; $partials[$k]['html'] = is_array($cb) ? call_user_func($cb, $rs, $k) : $cb($rs, $k); } } $page_title = $Title ? $Title : gTxt('write'); pagetop($page_title, $message); echo n . '<div id="' . $event . '_container" class="txp-container">'; echo n . n . '<form id="article_form" name="article_form" method="post" action="index.php" ' . ($step == 'create' ? '>' : ' class="async">'); if (!empty($store_out)) { echo hInput('store', base64_encode(serialize($store_out))); } echo hInput('ID', $ID) . n . eInput('article') . n . sInput($step) . n . hInput('sPosted', $sPosted) . n . hInput('sLastMod', $sLastMod) . n . hInput('AuthorID', $AuthorID) . n . hInput('LastModID', $LastModID) . '<input type="hidden" name="view" />' . startTable('', '', 'txp-columntable') . '<tr>' . n . '<td id="article-col-1"><div id="configuration_content">'; if ($view == 'text') { //-- markup help -------------- echo pluggable_ui('article_ui', 'sidehelp', side_help($textile_body, $textile_excerpt), $rs); //-- custom menu entries -------------- echo pluggable_ui('article_ui', 'extend_col_1', '', $rs); //-- advanced -------------- echo '<div id="advanced_group"><h3 class="lever' . (get_pref('pane_article_advanced_visible') ? ' expanded' : '') . '"><a href="#advanced">' . gTxt('advanced_options') . '</a></h3>' . '<div id="advanced" class="toggle" style="display:' . (get_pref('pane_article_advanced_visible') ? 'block' : 'none') . '">'; // markup selection echo pluggable_ui('article_ui', 'markup', n . graf('<label for="markup-body">' . gTxt('article_markup') . '</label>' . br . pref_text('textile_body', $textile_body, 'markup-body'), ' class="markup markup-body"') . n . graf('<label for="markup-excerpt">' . gTxt('excerpt_markup') . '</label>' . br . pref_text('textile_excerpt', $textile_excerpt, 'markup-excerpt'), ' class="markup markup-excerpt"'), $rs); // form override echo $allow_form_override ? pluggable_ui('article_ui', 'override', graf('<label for="override-form">' . gTxt('override_default_form') . '</label>' . sp . popHelp('override_form') . br . form_pop($override_form, 'override-form'), ' class="override-form"'), $rs) : ''; echo '</div></div>' . n; //-- custom fields -------------- echo $partials['custom_fields']['html']; //-- article image -------------- echo $partials['image']['html']; //-- meta info -------------- echo '<div id="meta_group"><h3 class="lever' . (get_pref('pane_article_meta_visible') ? ' expanded' : '') . '"><a href="#meta">' . gTxt('meta') . '</a></h3>' . '<div id="meta" class="toggle" style="display:' . (get_pref('pane_article_meta_visible') ? 'block' : 'none') . '">'; // keywords echo $partials['keywords']['html']; // url title echo $partials['url_title']['html']; echo '</div></div>' . n; //-- recent articles -------------- echo '<div id="recent_group"><h3 class="lever' . (get_pref('pane_article_recent_visible') ? ' expanded' : '') . '"><a href="#recent">' . gTxt('recent_articles') . '</a>' . '</h3>' . '<div id="recent" class="toggle" style="display:' . (get_pref('pane_article_recent_visible') ? 'block' : 'none') . '">'; echo $partials['recent_articles']['html']; echo '</div></div>'; } else { echo sp; } echo '</div></td>' . n . '<td id="article-main"><div id="main_content">'; //-- title input -------------- if ($view == 'preview') { echo '<div class="preview">' . hed(gTxt('preview'), 2) . hed($Title, 1, ' class="title"'); } elseif ($view == 'html') { echo '<div class="html">' . hed('HTML', 2) . hed($Title, 1, ' class="title"'); } elseif ($view == 'text') { echo '<div class="text">' . n . $partials['title']['html']; } //-- body -------------------- if ($view == 'preview') { echo '<div class="body">' . $Body_html . '</div>'; } elseif ($view == 'html') { echo tag(str_replace(array(n, t), array(br, sp . sp . sp . sp), txpspecialchars($Body_html)), 'code', ' class="body"'); } else { echo $partials['body']['html']; } //-- excerpt -------------------- if ($articles_use_excerpts) { if ($view == 'preview') { echo n . '<hr /><div class="excerpt">' . $Excerpt_html . '</div>'; } elseif ($view == 'html') { echo n . '<hr />' . tag(str_replace(array(n, t), array(br, sp . sp . sp . sp), txpspecialchars($Excerpt_html)), 'code', ' class="excerpt"'); } else { echo $partials['excerpt']['html']; } } //-- author -------------- if ($view == "text" && $step != "create") { echo $partials['author']['html']; } echo hInput('from_view', $view), '</div></div></td>'; //-- layer tabs ------------------- echo '<td id="article-tabs"><div id="view_modes">'; echo pluggable_ui('article_ui', 'view', $use_textile == USE_TEXTILE || $textile_body == USE_TEXTILE ? tag(tab('text', $view) . tab('html', $view) . tab('preview', $view), 'ul') : ' ', $rs); echo '</div></td>'; echo '<td id="article-col-2"><div id="supporting_content">'; if ($view == 'text') { if ($step != 'create') { echo n . graf(href(gtxt('create_new'), 'index.php?event=article'), ' class="action-create"'); } //-- prev/next article links -- if ($step != 'create' and ($rs['prev_id'] or $rs['next_id'])) { echo $partials['article_nav']['html']; } //-- status radios -------------- echo $partials['status']['html']; //-- sort and display ----------- echo pluggable_ui('article_ui', 'sort_display', n . n . tag(n . '<legend>' . gTxt('sort_display') . '</legend>' . $partials['section']['html'] . $partials['categories']['html'] . n, 'fieldset', ' id="write-sort"'), $rs); //-- "Comments" section echo n . n . '<div id="comments_group"' . ($use_comments == 1 ? '' : ' class="empty"') . '><h3 class="lever' . (get_pref('pane_article_comments_visible') ? ' expanded' : '') . '"><a href="#comments">' . gTxt('comment_settings') . '</a></h3>', '<div id="comments" class="toggle" style="display:' . (get_pref('pane_article_comments_visible') ? 'block' : 'none') . '">'; echo $partials['comments']['html']; // end "Comments" section echo '</div></div>'; //-- "Dates" section echo n . n . '<div id="dates_group"><h3 class="lever' . (get_pref('pane_article_dates_visible') ? ' expanded' : '') . '"><a href="#dates">' . gTxt('date_settings') . '</a></h3>', '<div id="dates" class="toggle" style="display:' . (get_pref('pane_article_dates_visible') ? 'block' : 'none') . '">'; if ($step == "create" and empty($GLOBALS['ID'])) { //-- timestamp ------------------- //Avoiding modified date to disappear $persist_timestamp = !empty($store_out['year']) ? safe_strtotime($store_out['year'] . '-' . $store_out['month'] . '-' . $store_out['day'] . ' ' . $store_out['hour'] . ':' . $store_out['minute'] . ':' . $store_out['second']) : time(); echo pluggable_ui('article_ui', 'timestamp', n . n . '<fieldset id="write-timestamp">' . n . '<legend>' . gTxt('timestamp') . '</legend>' . n . graf(checkbox('publish_now', '1', $publish_now, '', 'publish_now') . '<label for="publish_now">' . gTxt('set_to_now') . '</label>', ' class="publish-now"') . n . graf(gTxt('or_publish_at') . sp . popHelp('timestamp'), ' class="publish-at"') . n . graf('<span class="label">' . gtxt('date') . '</span>' . sp . tsi('year', '%Y', $persist_timestamp) . ' / ' . tsi('month', '%m', $persist_timestamp) . ' / ' . tsi('day', '%d', $persist_timestamp), ' class="date posted created"') . n . graf('<span class="label">' . gTxt('time') . '</span>' . sp . tsi('hour', '%H', $persist_timestamp) . ' : ' . tsi('minute', '%M', $persist_timestamp) . ' : ' . tsi('second', '%S', $persist_timestamp), ' class="time posted created"') . n . '</fieldset>', array('sPosted' => $persist_timestamp) + $rs); //-- expires ------------------- $persist_timestamp = !empty($store_out['exp_year']) ? safe_strtotime($store_out['exp_year'] . '-' . $store_out['exp_month'] . '-' . $store_out['exp_day'] . ' ' . $store_out['exp_hour'] . ':' . $store_out['exp_minute'] . ':' . $store_out['second']) : NULLDATETIME; echo pluggable_ui('article_ui', 'expires', n . n . '<fieldset id="write-expires">' . n . '<legend>' . gTxt('expires') . '</legend>' . n . graf('<span class="label">' . gtxt('date') . '</span>' . sp . tsi('exp_year', '%Y', $persist_timestamp) . ' / ' . tsi('exp_month', '%m', $persist_timestamp) . ' / ' . tsi('exp_day', '%d', $persist_timestamp), ' class="date expires"') . n . graf('<span class="label">' . gTxt('time') . '</span>' . sp . tsi('exp_hour', '%H', $persist_timestamp) . ' : ' . tsi('exp_minute', '%M', $persist_timestamp) . ' : ' . tsi('exp_second', '%S', $persist_timestamp), ' class="time expires"') . n . '</fieldset>', $rs); // end "Dates" section echo n . n . '</div></div>'; //-- publish button -------------- echo graf(has_privs('article.publish') ? fInput('submit', 'publish', gTxt('publish'), "publish", '', '', '', 4) : fInput('submit', 'publish', gTxt('save'), "publish", '', '', '', 4), ' id="write-publish"'); } else { //-- timestamp ------------------- echo $partials['posted']['html']; //-- expires ------------------- echo $partials['expires']['html']; // end "Dates" section echo n . n . '</div></div>'; //-- save button -------------- if ($Status >= STATUS_LIVE and has_privs('article.edit.published') or $Status >= STATUS_LIVE and $AuthorID == $txp_user and has_privs('article.edit.own.published') or $Status < STATUS_LIVE and has_privs('article.edit') or $Status < STATUS_LIVE and $AuthorID == $txp_user and has_privs('article.edit.own')) { echo graf(fInput('submit', 'save', gTxt('save'), "publish", '', '', '', 4), ' id="write-save"'); } } } echo '</div></td></tr></table>' . n . tInput() . n . '</form></div>' . n; // Assume users would not change the timestamp if they wanted to "publish now"/"reset time" echo script_js(<<<EOS \t\t\$('#write-timestamp input.year,#write-timestamp input.month,#write-timestamp input.day,#write-timestamp input.hour,#write-timestamp input.minute,#write-timestamp input.second').change( \t\t\tfunction() { \t\t\t\t\$('#publish_now').prop('checked', false); \t\t\t\t\$('#reset_time').prop('checked', false); \t\t\t}); EOS ); }
function ign_file_tab() { global $ign_levels; $id = gps('id'); if (!empty($id)) { $r = safe_field('permissions', 'txp_file', "id = '{$id}'"); } $select = addslashes(selectInput('perms', $ign_levels, @$r)); $select = str_replace("\n", '', $select); $select = str_replace("\t", '', $select); $js = "\$(\"#file-status\" ).after(\"<fieldset><legend>Permissions</legend>{$select}</fieldset>\");"; if (is_callable('script_js')) { echo script_js($js); } return; }
private function _announce($thing, $async, $modal) { // $thing[0]: message text. // $thing[1]: message type, defaults to "success" unless empty or a different flag is set. if (!is_array($thing) || !isset($thing[1])) { $thing = array($thing, 0); } // Still nothing to say? if (trim($thing[0]) === '') { return ''; } switch ($thing[1]) { case E_ERROR: $class = 'error'; break; case E_WARNING: $class = 'warning'; break; default: $class = 'success'; break; } if ($modal) { $html = ''; // TODO: Say what? $js = 'window.alert("' . escape_js(strip_tags($thing[0])) . '")'; } else { $html = span(gTxt($thing[0]) . sp . href('×', '#close', ' class="close" role="button" title="' . gTxt('close') . '" aria-label="' . gTxt('close') . '"'), array('class' => $class, 'id' => 'message', 'role' => 'alert')); // Try to inject $html into the message pane no matter when _announce()'s output is printed. $js = escape_js($html); $js = <<<EOS \$(document).ready(function () { \$("#messagepane").html("{$js}"); \$('#message.success, #message.warning, #message.error').fadeOut('fast').fadeIn('fast'); }); EOS; } if ($async) { return $js; } else { return script_js(str_replace('</', '<\\/', $js), $html); } }
function toggle_box($classname, $form = 0) { $name = 'cb_toggle_' . $classname; $i = '<input type="checkbox" name="' . $name . '" id="' . $name . '" value="1" ' . (cs('toggle_' . $classname) ? 'checked="checked" ' : '') . 'class="checkbox" onclick="toggleClassRemember(\'' . $classname . '\');" />' . ' <label for="' . $name . '">' . gTxt('detail_toggle') . '</label> ' . script_js("setClassRemember('" . $classname . "');addEvent(window, 'load', function(){setClassRemember('" . $classname . "');});"); if ($form) { return n . form($i); } else { return n . $i; } }
/** * Hooks to article saving process and updates short URLs */ public static function update() { global $prefs; if (empty($prefs['rah_bitly_login']) || empty($prefs['rah_bitly_apikey']) || empty($prefs['rah_bitly_field'])) { return; } static $old = array(); static $updated = false; $id = !empty($GLOBALS['ID']) ? $GLOBALS['ID'] : ps('ID'); if (!$id || ps('_txp_token') != form_token() || intval(ps('Status')) < 4) { $old = array('permlink' => NULL, 'status' => NULL); return; } include_once txpath . '/publish/taghandlers.php'; /* Get the old article permlink before anything is saved */ if (!$old) { $old = array('permlink' => permlinkurl_id($id), 'status' => fetch('Status', 'textpattern', 'ID', $id)); return; } /* Clear the permlink cache */ unset($GLOBALS['permlinks'][$id]); /* Generate a new if permlink has changed or if article is published */ if (callback_event('rah_bitly.update') !== '') { return; } if ($updated == false && ($permlink = permlinkurl_id($id)) && ($old['permlink'] != $permlink || !ps('custom_' . $prefs['rah_bitly_field']) || $old['status'] != ps('Status'))) { $uri = self::fetch($permlink); if ($uri) { $fields = getCustomFields(); if (!isset($fields[$prefs['rah_bitly_field']])) { return; } safe_update('textpattern', 'custom_' . intval($prefs['rah_bitly_field']) . "='" . doSlash($uri) . "'", "ID='" . doSlash($id) . "'"); $_POST['custom_' . $prefs['rah_bitly_field']] = $uri; } $updated = true; } if (!empty($uri)) { echo script_js('$(\'input[name="custom_' . $prefs['rah_bitly_field'] . '"]\').val("' . escape_js($uri) . '");'); } }
function is_dst($name, $val) { $ui = yesnoRadio($name, $val) . n . script_js("textpattern.timezone_is_supported = " . (int) timezone::is_supported() . ";") . script_js(<<<EOS \t\t\t\$(document).ready(function(){ \t\t\t\tvar radio = \$("#prefs-is_dst input"); \t\t\t\tif (radio) { \t\t\t\t\tif (\$("#auto_dst-1").attr("checked") && textpattern.timezone_is_supported) { \t\t\t\t\t\tradio.attr("disabled","disabled"); \t\t\t\t\t} \t\t\t\t\t\$("#auto_dst-0").click( \t\t\t\t\t\tfunction(){ \t\t\t\t\t\t\tradio.removeAttr("disabled"); \t\t\t\t\t\t}); \t\t\t\t \t\$("#auto_dst-1").click( \t\t\t\t\t\tfunction(){ \t\t\t\t\t\t\tradio.attr("disabled","disabled"); \t\t\t\t\t \t}); \t\t\t \t} \t\t\t\tif (!textpattern.timezone_is_supported) { \t\t\t\t\t\$("#prefs-auto_dst input").attr("disabled","disabled"); \t\t\t\t} \t}); EOS ); return pluggable_ui('prefs_ui', 'is_dst', $ui, $name, $val); }
function category_2($rs) { // Render the same markup as core and make some noise about it. return category_popup('Category2', $rs['Category2'], 'category-2') . script_js('alert("Woot!")'); }