<?php /** * Back-End of Pagemanager_XH. * * Copyright (c) 2011-2012 Christoph M. Becker (see license.txt) */ // utf-8-marker: äöüß if (!defined('CMSIMPLE_XH_VERSION')) { header('HTTP/1.0 403 Forbidden'); exit; } define('PAGEMANAGER_VERSION', 'CMSimple4_v1.1'); $plugin_cf['pagemanager']['verbose']="true"; $plugin_cf['pagemanager']['pagedata_attribute']=$cf['pagemanager']['pagedata_attribute']; $plugin_cf['pagemanager']['toolbar_show']="true"; $plugin_cf['pagemanager']['toolbar_vertical']="false"; $plugin_cf['pagemanager']['treeview_theme']="cmsimple"; $plugin_cf['pagemanager']['treeview_animation']="200"; /** * Reads content.htm and sets $pagemanager_h. * * The function was copied from CMSimple_XH 1.4's cms.php and modified * to just set the global $pagemanager_h with the unmodified page titles * and $pagemanager_no_rename wether the heading is partially formatted. * * @return void */ function pagemanager_rfc() { global $pth, $tx, $cf, $pagemanager_h, $pagemanager_no_rename; $c = array(); $pagemanager_h = array(); $u = array(); $l = array(); $empty = 0; $duplicate = 0; $content = file_get_contents($pth['file']['content']); $stop = $cf['menu']['levels']; $split_token = '#@CMSIMPLE_SPLIT@#'; $content = preg_split('~</body>~i', $content); $content = preg_replace('~<h[1-' . $stop . ']~i', $split_token . '$0', $content[0]); $content = explode($split_token, $content); array_shift($content); foreach ($content as $page) { $c[] = $page; preg_match('~<h([1-' . $stop . ']).*>(.*)</h~isU', $page, $temp); $l[] = $temp[1]; $temp_h[] = trim(strip_tags($temp[2])); $pagemanager_no_rename[] = preg_match('/.*?<.*?/isU', $temp[2]); } $cl = count($c); $s = -1; if ($cl == 0) { $c[] = '<h1>' . $tx['toc']['newpage'] . '</h1>'; $pagemanager_h[] = trim(strip_tags($tx['toc']['newpage'])); $pagemanager_no_rename[] = preg_match('/.*?<.*?/isU', $tx['toc']['newpage']); $l[] = 1; $s = 0; return; } foreach ($temp_h as $i => $pagemanager_heading) { if ($pagemanager_heading == '') { $empty++; $pagemanager_heading = $tx['toc']['empty'] . ' ' . $empty; } $pagemanager_h[$i] = $pagemanager_heading; } } /** * Returns plugin version information. * * @return string */ function pagemanager_version() { global $tx; return '<br /><hr /><p>' . $tx['message']['plugin_standard1'] . '</p><p>' . $tx['message']['plugin_standard2'] . ' <a href="./?file=config&action=array"><b>' . $tx['filetype']['config'] . '</b></a></p>' .tag('hr').'<p><strong>Pagemanager_XH</strong></p>'."\n" .'<p>Version: '.PAGEMANAGER_VERSION.'</p>'."\n" .'<p><b>Author:</b> Copyright © 2011-2012 <a href="http://3-magi.net">Christoph M. Becker</a></p>'."\n" .'<p>Adapted for CMSimple 4.0 and higher by <a href="http://www.ge-webdesign.de/" target="_blank">ge-webdesign.de</a></p>' .'<p><a href="http://3-magi.net/?CMSimple_XH/Pagemanager_XH">' .'Pagemanager_XH</a> is powered by ' .'<a href="http://www.cmsimple-xh.com/wiki/doku.php/plugins:jquery4cmsimple">' .'jQuery4CMSimple</a>' .' and <a href="http://www.jstree.com/">jsTree</a>.</p>'."\n" .'<p style="text-align: justify">This program is free software: you can redistribute it and/or modify' .' it under the terms of the GNU General Public License as published by' .' the Free Software Foundation, either version 3 of the License, or' .' (at your option) any later version.</p>'."\n" .'<p style="text-align: justify">This program is distributed in the hope that it will be useful,' .' but WITHOUT ANY WARRANTY; without even the implied warranty of' .' MERCHAN­TABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the' .' GNU General Public License for more details.</p>'."\n" .'<p style="text-align: justify">You should have received a copy of the GNU General Public License' .' along with this program. If not, see' .' <a href="http://www.gnu.org/licenses/">http://www.gnu.org/licenses/</a>.</p>'."\n"; } /** * Returns the toolbar. * * @param string $image_ext The image extension (.gif or .png). * @param string $save_js The js code for onclick. * @return string The (x)html. */ function pagemanager_toolbar($image_ext, $save_js) { global $pth, $plugin_cf, $tx; $imgdir = $pth['folder']['plugins'].'pagemanager/images/'; $horizontal = strtolower($plugin_cf['pagemanager']['toolbar_vertical']) != 'true'; $res = '<div id="pagemanager-toolbar" class="'.($horizontal ? 'horizontal' : 'vertical').'">'."\n"; $toolbar = array('save', 'separator', 'expand', 'collapse', 'separator', 'create', 'create_after', 'rename', 'delete', 'separator', 'cut', 'copy', 'paste', 'paste_after', 'separator', 'help'); foreach ($toolbar as $tool) { $link = ($tool != 'help' ? 'href="#"' : 'href="'.$pth['file']['plugin_help'].'" target="_blank"'); $img = $imgdir.$tool.($tool != 'separator' || !$horizontal ? '' : '_v').$image_ext; $class = $tool == 'separator' ? 'separator' : 'tool'; $res .= ($tool != 'separator' ? '<a '.$link.' class="pl_tooltip"'.($tool == 'save' ? ' style="display: none"' : '').'>' : '') .tag('img class="'.$class.'" src="'.$img.'"' .($tool != 'help' ? ' onclick="pagemanager_do(\''.$tool.'\'); return false;"' : '')) .($tool != 'separator' ? '<span>'.($tool == 'save' ? ucfirst($tx['action']['save']) : $tx['pagemanager']['op_'.$tool]).'</span></a>' : '') .($horizontal ? '' : tag('br'))."\n"; } $res .= '</div>'."\n"; return $res; } /** * Instanciate the pagemanager.js template. * * @param string $image_ext The image extension (.gif or .png). * @return string The (x)html. */ function pagemanager_instanciateJS($image_ext) { global $pth, $plugin_cf, $cf, $tx; $js = rf($pth['folder']['plugins'].'pagemanager/pagemanager.js'); preg_match_all('/<<<PC_(.*)>>>/', $js, $options); foreach ($options[1] as $opt) { $pagemanager_cf[$opt] = addcslashes($plugin_cf['pagemanager'][$opt], "\0'\"\\\f\n\r\t\v"); } preg_match_all('/<<<PT_(.*)>>>/', $js, $options); foreach ($options[1] as $opt) $pagemanager_tx[$opt] = addcslashes($tx['pagemanager'][$opt], "\0'\"\\\f\n\r\t\v"); // replace config variables $js = str_replace('<<<PC_verbose>>>', 'true', $js); $js = str_replace('<<<PC_treeview_animation>>>', '200', $js); $js = str_replace('<<<PC_treeview_theme>>>', 'cmsimple', $js); // replace language variables $js = str_replace('<<<PT_button_cancel>>>', $pagemanager_tx["button_cancel"], $js); $js = str_replace('<<<PT_button_delete>>>', $pagemanager_tx["button_delete"], $js); $js = str_replace('<<<PT_button_ok>>>', $pagemanager_tx["button_ok"], $js); $js = str_replace('<<<PT_error_cant_rename>>>', $pagemanager_tx["error_cant_rename"], $js); $js = str_replace('<<<PT_error_offending_extension>>>', $pagemanager_tx["error_offending_extension"], $js); $js = str_replace('<<<PT_message_confirm_deletion>>>', $pagemanager_tx["message_confirm_deletion"], $js); $js = str_replace('<<<PT_message_confirm_leave>>>', $pagemanager_tx["message_confirm_leave"], $js); $js = str_replace('<<<PT_message_delete_last>>>', $pagemanager_tx["message_delete_last"], $js); $js = str_replace('<<<PT_message_menu_level>>>', $pagemanager_tx["message_menu_level"], $js); $js = str_replace('<<<PT_message_no_selection>>>', $pagemanager_tx["message_no_selection"], $js); $js = str_replace('<<<PT_message_warning_leave>>>', $pagemanager_tx["message_warning_leave"], $js); $js = str_replace('<<<PT_op_create>>>', $pagemanager_tx["op_create"], $js); $js = str_replace('<<<PT_op_create_after>>>', $pagemanager_tx["op_create_after"], $js); $js = str_replace('<<<PT_op_rename>>>', $pagemanager_tx["op_rename"], $js); $js = str_replace('<<<PT_op_delete>>>', $pagemanager_tx["op_delete"], $js); $js = str_replace('<<<PT_op_cut>>>', $pagemanager_tx["op_cut"], $js); $js = str_replace('<<<PT_op_copy>>>', $pagemanager_tx["op_copy"], $js); $js = str_replace('<<<PT_op_paste>>>', $pagemanager_tx["op_paste"], $js); $js = str_replace('<<<PT_op_paste_after>>>', $pagemanager_tx["op_paste_after"], $js); $js = str_replace('<<<PT_treeview_loading>>>', $pagemanager_tx["treeview_loading"], $js); $js = str_replace('<<<PT_treeview_new>>>', $pagemanager_tx["treeview_new"], $js); // replace the rest $js = str_replace('<<<MENU_LEVELS>>>', $cf['menu']['levels'], $js); $js = str_replace('<<<TOC_DUPL>>>', $tx['toc']['dupl'], $js); $js = str_replace('<<<IMAGE_EXT>>>', $image_ext, $js); $js = str_replace('<<<IMAGE_DIR>>>', $pth['folder']['plugins'].'pagemanager/images/', $js); return '<!-- initialize jstree -->'."\n" .'<script type="text/javascript">'."\n" .'/* <![CDATA[ */'.$js.'/* ]]> */'."\n" .'</script>'."\n"; } /** * Emits the page administration (X)HTML. * * @return void */ function pagemanager_edit() { global $hjs, $pth, $o, $sn, $h, $l, $plugin, $plugin_cf, $tx, $u, $pagemanager_h, $pagemanager_no_rename, $pd_router; include_once($pth['folder']['plugins'].'jquery/jquery.inc.php'); include_jQuery(); include_jQueryUI(); include_jQueryPlugin('jsTree', $pth['folder']['plugins'] .'pagemanager/jstree/jquery.jstree.js'); $image_ext = (file_exists($pth['folder']['plugins'].'pagemanager/images/help.png')) ? '.png' : '.gif'; pagemanager_rfc(); $bo = ''; $swo = '<div id="pagemanager-structure-warning" class="cmsimplecore_warning"><p>' .$tx['pagemanager']['error_structure_warning'] .'</p><p><a href="javascript:pagemanager_confirmStructureWarning();">' .$tx['pagemanager']['error_structure_confirmation'] .'</a></div>'."\n"; $save_js = 'jQuery(\'#pagemanager-xml\')[0].value =' .' jQuery(\'#pagemanager\').jstree(\'get_xml\', \'nest\', -1, new Array(\'id\', \'title\', \'pdattr\'))'; $xhpages = isset($_GET['xhpages']) ? '&pagemanager-xhpages' : ''; $bo .= '<form id="pagemanager-form" action="'.$sn.'?&pagemanager&edit'.$xhpages.'" method="post">'."\n"; $bo .= strtolower($plugin_cf['pagemanager']['toolbar_show']) == 'true' ? pagemanager_toolbar($image_ext, $save_js) : ''; // output the treeview of the page structure // uses ugly hack to clean up irregular page structure $irregular = FALSE; $pd = $pd_router->find_page(0); $bo .= '<!-- page structure -->'."\n" .'<div id="pagemanager" ondblclick="jQuery(\'#pagemanager\').jstree(\'toggle_node\');">'."\n" .'<ul>'."\n".'<li id="pagemanager-0" title="'.$pagemanager_h[0].'"' .' pdattr="'.($pd[$plugin_cf['pagemanager']['pagedata_attribute']] == '' ? '1' : $pd[$plugin_cf['pagemanager']['pagedata_attribute']]).'"' .($pagemanager_no_rename[0] ? ' class="pagemanager-no-rename"' : '') .'><a href="#">'.$pagemanager_h[0].'</a>'; $stack = array(); for ($i = 1; $i < count($h); $i++) { $ldiff = $l[$i] - $l[$i-1]; if ($ldiff <= 0) { // same level or decreasing $bo .= '</li>'."\n"; if ($ldiff != 0 && count($stack) > 0) { $jdiff = array_pop($stack); if ($jdiff + $ldiff > 0) { array_push($stack, $jdiff + $ldiff); $ldiff = 0; } else { $ldiff += $jdiff - 1; } } for ($j = $ldiff; $j < 0; $j++) $bo .= '</ul></li>'."\n"; } else { // level increasing if ($ldiff > 1) { array_push($stack, $ldiff); $irregular = TRUE; } $bo .= "\n".'<ul>'."\n"; } $pd = $pd_router->find_page($i); $bo .= '<li id="pagemanager-'.$i.'"' .' title="'.$pagemanager_h[$i].'"' .' pdattr="'.($pd[$plugin_cf['pagemanager']['pagedata_attribute']] == '' ? '1' : $pd[$plugin_cf['pagemanager']['pagedata_attribute']]).'"' .($pagemanager_no_rename[$i] ? ' class="pagemanager-no-rename"' : '') .'><a href="#">'.$pagemanager_h[$i].'</a>'; } $bo .= '</ul></div>'."\n"; if ($irregular) $o .= $swo; $o .= $bo; $o .= pagemanager_instanciateJS($image_ext); // HACK?: send 'edit' as query param to prevent the last if clause in // rfc() to insert #CMSimple hide# $o .= tag('input type="hidden" name="admin" value=""')."\n" .tag('input type="hidden" name="action" value="plugin_save"')."\n" .tag('input type="hidden" name="xml" id="pagemanager-xml" value=""')."\n" .tag('input id="pagemanager-submit" type="submit" class="submit" value="' .ucfirst($tx['action']['save']).'"' .' onclick="'.$save_js.'"' .' style="display: none"')."\n" .'</form>'."\n" .'<div id="pagemanager-footer"> </div>'."\n"; $o .= '<div id="pagemanager-confirmation" title="' . $tx['pagemanager']['message_confirm'] . '?"></div>'."\n" .'<div id="pagemanager-alert" title=\'' .tag('img src="'.$pth['folder']['plugins'].'pagemanager/images/problem'.$image_ext.'"') .' '.$tx['pagemanager']['message_information'].'\'></div>'."\n"; } /** * Handles start elements of jsTree's xml result. * * @return void */ function pagemanager_start_element_handler($parser, $name, $attribs) { global $o, $pagemanager_state; if ($name == 'ITEM') { $pagemanager_state['level']++; $pagemanager_state['id'] = $attribs['ID'] == '' ? '' : preg_replace('/(copy_)?pagemanager-([0-9]*)/', '$2', $attribs['ID']); $pagemanager_state['title'] = htmlspecialchars($attribs['TITLE']); $pagemanager_state['pdattr'] = $attribs['PDATTR']; $pagemanager_state['num']++; } } /** * Handles end elements of jsTree's xml result. * * @return void */ function pagemanager_end_element_handler($parser, $name) { global $pagemanager_state; if ($name == 'ITEM') $pagemanager_state['level']--; } /** * Handles character data of jsTree's xml result. * * @return void */ function pagemanager_cdata_handler($parser, $data) { global $c, $h, $cf, $pagemanager_fp, $pagemanager_state, $pagemanager_pd, $pd_router, $plugin_cf; $data = htmlspecialchars($data); if (isset($c[$pagemanager_state['id']])) { $cnt = $c[$pagemanager_state['id']]; $cnt = preg_replace('/<h[1-'.$cf['menu']['levels'].']([^>]*)>' .'((<[^>]*>)*)[^<]*((<[^>]*>)*)<\/h[1-'.$cf['menu']['levels'].']([^>]*)>/i', '<h'.$pagemanager_state['level'].'$1>${2}'.addcslashes($pagemanager_state['title'], '$\\').'$4' .'</h'.$pagemanager_state['level'].'$6>', $cnt, 1); fwrite($pagemanager_fp, rmnl($cnt."\n")); } else { fwrite($pagemanager_fp, '<h'.$pagemanager_state['level'].'>'.$pagemanager_state['title'] .'</h'.$pagemanager_state['level'].'>'."\n"); } if ($pagemanager_state['id'] == '') { $pd = $pd_router->new_page(array()); } else { $pd = $pd_router->find_page($pagemanager_state['id']); } $pd['url'] = uenc($pagemanager_state['title']); $pd[$plugin_cf['pagemanager']['pagedata_attribute']] = $pagemanager_state['pdattr']; $pagemanager_pd[] = $pd; } /** * Saves content.htm manually and * pagedata.php via $pd_router->model->refresh(). * * @return void */ function pagemanager_save($xml) { global $pth, $tx, $pd_router, $pagemanager_state, $pagemanager_fp, $pagemanager_pd; $pagemanager_pd = array(); $parser = xml_parser_create('UTF-8'); xml_set_element_handler($parser, 'pagemanager_start_element_handler', 'pagemanager_end_element_handler'); xml_set_character_data_handler($parser, 'pagemanager_cdata_handler'); $pagemanager_state['level'] = 0; $pagemanager_state['num'] = -1; if ($pagemanager_fp = fopen($pth['file']['content'], 'w')) { fputs($pagemanager_fp, '<html><head><title>Content</title></head><body>'."\n"); xml_parse($parser, $xml, TRUE); fputs($pagemanager_fp, '</body></html>'); fclose($pagemanager_fp); $pd_router->model->refresh($pagemanager_pd); } else e('cntwriteto', 'content', $pth['file']['content']); rfc(); // is neccessary, if relocation fails! } /** * Hook into new edit menu of CMSimple_XH 1.5 */ if ($f === 'xhpages' && isset($cf['pagemanager']['external']) && in_array($cf['pagemanager']['external'], array('', 'pagemanager'))) { pagemanager_edit(); } /** * Plugin administration */ if (isset($pagemanager)) { // check requirements (RELEASE-TODO) define('PAGEMANAGER_PHP_VERSION', '4.3.0'); if (version_compare(PHP_VERSION, PAGEMANAGER_PHP_VERSION) < 0) $e .= '<li>'.sprintf($tx['pagemanager']['error_phpversion'], PAGEMANAGER_PHP_VERSION).'</li>'."\n"; foreach (array('pcre', 'xml') as $ext) { if (!extension_loaded($ext)) $e .= '<li>'.sprintf($tx['pagemanager']['error_extension'], $ext).'</li>'."\n"; } if (!file_exists($pth['folder']['plugins'].'jquery/jquery.inc.php')) $e .= '<li>'.$tx['pagemanager']['error_jquery'].'</li>'."\n"; if (strtolower($tx['meta']['codepage']) != 'utf-8') { $e .= '<li>'.$tx['pagemanager']['error_encoding'].'</li>'."\n"; } initvar('admin'); initvar('action'); $o .= print_plugin_admin('on'); switch ($admin) { case '': if ($action == 'plugin_save') { pagemanager_save(stsl($_POST['xml'])); if (!headers_sent()) { header('Location: http://'.$_SERVER['SERVER_NAME'].$sn .(isset($_GET['pagemanager-xhpages']) ? '?&normal&xhpages' : '?&pagemanager&normal&admin=plugin_main')); } exit(); } else { $o .= pagemanager_version(); } break; case 'plugin_main': pagemanager_edit(); break; default: $o .= plugin_admin_common($action, $admin, $plugin); } } ?>