* @copyright 2004-2005 by gERD Schaufelberger * @package wombat * @subpackage admin */ /** * Site Maker Admin Interface * * SiteMaker is capable to create/maintain pages. This is done by * reading/writing page-configuration files ()conf/pages/*.xml) * Furthermore it includes the MenuMaker which is capable to create * tree menue by arranging existing pages. Also SiteMaker allows to * start the CMS-Browser. * * * @version 1.3.0 * @package wombat * @subpackage Admin */ class wbAdminApp_SiteMaker extends wbAdminApp { /** * default values for request variables * @access protected * @var array $_requestDefaults * @see $_request */ var $_requestDefaults = array( 'action' => '_no_action_', 'page' => null, 'part' => null, 'href' => null, ); /** * name of this application * @var string $_appName */ var $_appName = 'SiteMaker'; /** * list of pages * @var array $_pages */ var $_pages = array(); /** * meue items * @var array $_menu */ var $_menu = array(); /** * patConfiguration object * @var object $_conf */ var $_conf; /** * run admin interface * * @access public * @param array $path * @return boolean true on success */ function process( $path ) { $this->_conf =& wbFactory::singleton( 'patConfiguration' ); $app = array_shift( $path ); switch( $app ) { case 'Page': $this->_processPageMaker( $path ); break; case 'Menu': $this->_processMenuMaker( $path ); break; case 'Browse': $this->_loadTemplates( 'browse' ); break; case 'Jump': $this->_loadTemplates( 'jump' ); $jump = array( 'page' => $this->_request['page'], 'part' => $this->_request['part'], 'href' => $this->_request['href'], ); $this->_tmpl->addGlobalVars( $jump, 'JUMP_' ); break; default: $this->_loadTemplates( 'index' ); break; } return true; } /** * run page maker * * @access private * @param array $path * @return boolean true on success */ function _processPageMaker( $path ) { $action = 'List'; if( !empty( $path) ) { $action = array_shift( $path ); } $pageConfig = array(); $pageName = $this->_request['page']; $this->_tmpl->addGlobalVar( 'page', $pageName ); // all actions beside "List" and "New" require a page id if( !in_array( $action, array( 'New', 'List', 'Copy' ) ) && $pageName ) { $pageConfig = $this->_getPage( $pageName ); if( patErrorManager::isError( $pageConfig ) ) { $pageConfig = array(); $action = 'List'; $path = array(); } } switch( $action ) { case 'View': $this->_pageView( $pageName, $pageConfig ); break; case 'Edit': $this->_pageEdit( $pageName, $pageConfig ); break; case 'New': $this->_pageEdit( '_new', $pageConfig ); break; case 'Copy': $this->_pageCopy( $path ); break; case 'Delete'; $this->_pageDelete( $pageName, $pageConfig ); break; // page list case 'List': default: $this->_pageList(); break; } return true; } /** * run menu maker * * @access private * @return boolean true on success */ function _processMenuMaker( $path ) { wbFactory::includeClass( 'wbMenuTools' ); // save menu? if( $this->_request['action'] == 'save' ) { if( !$this->_checkReload() ) { $this->_storeMenu(); } $this->_addMsg( _( 'Menu saved!' ) ); } $this->_loadTemplates( 'menu' ); $this->_loadTemplates( 'submit', false ); $this->_tmpl->addVar( 'submit', 'callback', 'menu' ); // set menu builder javascript options $debug = 'false'; $deleteRoot = 'false'; if( wbDebugger::isActive() ) { $debug = 'true'; } if( isset( $this->_config['deleteroot'] ) && $this->_config['deleteroot'] ) { $deleteRoot = 'true'; } $this->_tmpl->addVar( 'onload', 'debug', $debug ); $this->_tmpl->addVar( 'onload', 'deleterootitem', $deleteRoot ); $load = $this->_tmpl->getParsedTemplate( 'onload' ); wbJSTools::includeJavascript( $load, 'onload' ); wbJSTools::includeJavascript( 'wbMenu.js' ); wbJSTools::includeJavascript( 'wbMenuMaker.js' ); $this->_loadMenu(); $flat = wbMenuTools::getFlatMenu(); if( patErrorManager::isError( $flat ) ) { return $flat; } $this->_tmpl->addRows( 'menuitem_entry', $flat ); // add page list $pages =& $this->_getPageList( true ); $this->_tmpl->addRows( 'page_entry', $pages ); return true; } /** * display list of paged * * @access private * @return boolean true on success */ function _pageList() { $this->_loadTemplates( 'page_list' ); $pages =& $this->_getPageList(); $this->_tmpl->addRows( 'page_entry', $pages ); return true; } /** * display list of paged * * @access private * @return boolean true on success */ function &_getPageList( $quote = false ) { $this->_loadPageList(); $pages = array(); foreach( $this->_pages as $key => $value ) { $page = array( 'name' => $key ); foreach( $value as $k => $v ) { if( is_array( $v ) ) { continue; } if( $quote ) { $v = addslashes( $v ); } $page[$k] = $v; } array_push( $pages, $page ); } // sort and display usort( $pages, array( $this, '_comparePage' ) ); return $pages; } /** * didsplay page details * * @access private * @param string $pageName name of the page to be displayed * @param array $pageConfig setting if the page * @return boolean true on success */ function _pageView( $pageName, &$pageConfig ) { $this->_loadTemplates( 'page_view' ); $content = array(); if( isset( $pageConfig['content'] ) ) { $content = $pageConfig['content']; unset( $pageConfig['content'] ); } $auth = array(); if( isset( $pageConfig['auth'] ) ) { $auth = $pageConfig['auth']; unset( $pageConfig['auth'] ); } $contentView = array(); foreach( $this->_config['page'] as $part => $actions ) { if( empty( $actions ) ) { continue; } if( !isset( $content[$part] ) ) { array_push( $contentView, array( 'part' => $part ) ); continue; } $content[$part]['part'] = $part; if( isset( $content[$part]['params'] ) ) { $params = array(); foreach( $content[$part]['params'] as $key => $value ) { array_push( $params, $key . '=' . $value ); } $content[$part]['params'] = implode( "\n", $params ); } array_push( $contentView, $content[$part] ); } $this->_tmpl->addVars( 'page_basic', $pageConfig ); $this->_tmpl->addVars( 'page_auth', $auth ); $this->_tmpl->addRows( 'page_content_entry', $contentView ); // add tab-bar wbJSTools::includeJavascript( 'displayTab( "basic" );', 'onload' ); return true; } /** * didsplay page editor * * @access private * @param string $pageName name of the page to be displayed * @param array $pageConfig setting if the page * @return boolean true on success */ function _pageEdit( $pageName, &$pageConfig ) { $this->_loadTemplates( 'submit', false ); $this->_loadTemplates( 'formErrors', false ); $data = array( 'name' => '' ); if( $pageName != '_new' ) { // are we allowed to edit this page? if( !$pageConfig['edit'] ) { return $this->_pageView( $pageName, $pageConfig ); } $data['name'] = $pageName; $data['title'] = $pageConfig['title']; $data['brief'] = $pageConfig['brief']; } // translate authorisation configuration if( isset( $pageConfig['auth'] ) ) { if( isset( $pageConfig['auth']['module'] ) ) { $data['auth_module'] = $pageConfig['auth']['module']; if( isset( $pageConfig['auth']['param'] ) ) { $data['auth_param'] = $pageConfig['auth']['param']; } } } // translate data for each content part foreach( $this->_config['page'] as $part => $actions ) { // don't configure parts that are not allowed to! if( empty( $actions ) ) { continue; } // load values from actual content if( isset( $pageConfig['content'][$part] ) && !empty( $pageConfig['content'][$part] ) ) { $data['part_'. $part . '_default'] = ''; $data['part_'. $part . '_action'] = $pageConfig['content'][$part]['action']; foreach( $actions as $action ) { if( $action == $pageConfig['content'][$part]['action'] ) { $data['part_'. $part . '_' . $action . '_href'] = $pageConfig['content'][$part]['href']; if( isset( $pageConfig['content'][$part]['params'] ) ) { $params = array(); foreach( $pageConfig['content'][$part]['params'] as $key => $value ) { array_push( $params, $key . '=' . $value ); } $data['part_'. $part . '_' . $action . '_params'] = implode( "\n", $params ); } } } } else { $data['part_'. $part . '_default'] = 'yes'; $data['part_'. $part . '_action'] = ''; } } $this->_tmpl->addGlobalVar( 'page', $pageName ); wbFactory::includeClass( 'patForms' ); $formBasic = array(); $formAuth = array(); $formContent = array(); $formRules = array(); $formDef = $this->_getPageFormDef( $formBasic, $formAuth, $formContent, $formRules ); $form =& wbFactory::create( 'patForms', array( 'elements' => $formDef ) ); $trimmer =& patForms::createFilter( 'Trim' ); $filename =& patForms::createRule( 'RegexReplace' ); // make name as possible filename $el =& $form->getElementByName( 'name' ); $el->addRule( $filename, PATFORMS_RULE_BEFORE_VALIDATION ); // trim all! $form->applyFilter( $trimmer ); // add condition to all foreach( $this->_config['page'] as $part => $actions ) { // don't configure parts that are not allowed to! if( empty( $actions ) ) { continue; } foreach( $actions as $action ) { $condition =& patForms::createRule( 'ConditionalRequired' ); $condition->addCondition( 'part_' . $part . '_default', '' ); $condition->addCondition( 'part_' . $part . '_action', $action ); $condition->setRequiredFields( array( 'part_' . $part . '_' . $action . '_href' ) ); $form->addRule( $condition, PATFORMS_RULE_BEFORE_VALIDATION ); } } // add element rules for( $i = 0; $i < count( $formRules ); ++$i ) { $form->addRule( $formRules[$i], PATFORMS_RULE_BEFORE_VALIDATION ); } // process data if( $this->_request['action'] == 'save' ) { $form->setSubmitted( true ); if( $form->validateForm() ) { $data = $form->getValues(); if( !$this->_checkReload() ) { $this->_storePage( $pageName, $data ); } // go to edit page! if( $pageName == '_new' ) { $this->_addMsg( _( 'Details of new page "{TITLE}" saved' ), $data ); } else { $this->_addMsg( _( 'Details of page "{TITLE}" saved' ), $data ); } return $this->_pageList(); } else { $this->_displayFormErrors( $form ); } } else { $form->setValues( $data ); } $renderer =& patForms::createRenderer( 'Array' ); $form->setRenderer( $renderer ); $elements = $form->renderForm(); $elementsBase = array(); $elementsAuth = array(); $elementsContent = array(); // separete elemente to suit design... for( $i = 0; $i < count( $elements ); ++$i ) { if( in_array( $elements[$i]['name'], $formBasic ) ) { array_push( $elementsBase, $elements[$i] ); } else if( in_array( $elements[$i]['name'], $formAuth ) ) { array_push( $elementsAuth, $elements[$i] ); } else { $elementsContent[$elements[$i]['name']] = $elements[$i]; } } $this->_loadTemplates( 'page_edit' ); wbJSTools::includeJavascript( 'wbSiteMaker.js' ); $elContent = array(); foreach( $this->_config['page'] as $part => $actions ) { // don't configure parts that are not allowed to! if( empty( $actions ) ) { continue; } $el = array( 'part' => ucfirst( $part ) ); wbDebugger::addMsg( 'SiteMaker', 'Available actions "'. implode( '", "', $actions ) . '"', 'Content:' . $part ); // action selector $this->_tmpl->clearTemplate( 'content_actiontab' ); $this->_tmpl->clearTemplate( 'content_actiontab_entry' ); $this->_tmpl->addVar( 'content_actiontab', 'part', $part ); $this->_tmpl->addVar( 'content_actiontab', 'actions', implode( ',', $actions ) ); $this->_tmpl->addVar( 'content_actiontab_entry', 'part', $part ); $this->_tmpl->addVar( 'content_actiontab_entry', 'action', $actions ); $el['actiontab'] = $this->_tmpl->getParsedTemplate( 'content_actiontab' ); foreach( $elementsContent['part_' . $part . '_default'] as $key => $value ) { $el['default_' .$key] = $value; } foreach( $elementsContent['part_' . $part . '_action'] as $key => $value ) { $el['action_' .$key] = $value; } // action form $actionConfig = array(); foreach( $actions as $action ) { $this->_tmpl->clearTemplate( 'content_actionconfig' ); $this->_tmpl->clearTemplate( 'content_actionconfig_entry' ); $this->_tmpl->addVar( 'content_actionconfig', 'part', $part ); $this->_tmpl->addVar( 'content_actionconfig', 'action', $action ); // add all elements required for this action $elConfig = array(); foreach( $formContent[$part][$action] as $key ) { array_push( $elConfig, $elementsContent['part_' . $part . '_' . $action . '_' . $key] ); } $this->_tmpl->addRows( 'content_actionconfig_entry', $elConfig ); array_push( $actionConfig, $this->_tmpl->getParsedTemplate( 'content_actionconfig' ) ); } $el['actionconfig'] = implode( "\n", $actionConfig ); array_push( $elContent, $el ); // display correct action tab if( $data['part_' . $part . '_action'] ) { wbJSTools::includeJavascript( 'displayAction( "'.$part.'", "'. $data['part_' . $part . '_action'] .'" );', 'onload' ); } else { wbJSTools::includeJavascript( 'displayAction( "'.$part.'", "'. $actions[0] .'" );', 'onload' ); } } $this->_tmpl->addRows( 'basic_entry', $elementsBase ); $this->_tmpl->addRows( 'auth_entry', $elementsAuth ); $this->_tmpl->addRows( 'content_entry', $elContent ); wbJSTools::includeJavascript( 'displayTab( "basic" );', 'onload' ); return true; } /** * didsplay page editor - delete a page * * @access private * @param string $pageName name of the page to be displayed * @param array $pageConfig setting if the page * @return boolean true on success */ function _pageDelete( $page, &$pageConfig ) { if( isset( $pageConfig['content'] ) ) { unset( $pageConfig['content'] ); } if( isset( $pageConfig['auth'] ) ) { unset( $pageConfig['auth'] ); } // delete page for real if( $this->_request['action'] == 'force' ) { if( !$this->_checkReload() ) { wbDebugger::addMsg( 'SiteMaker', 'Removed page "'. $page . '"', 'Page' ); $confDir = wbFactory::getParam( 'baseDir' ) . '/' . wbFactory::getParam( 'configDir' ); unlink( $confDir . '/pages/' . $page . '.xml' ); unset( $this->_request['page'] ); } $this->_addMsg( _( 'Page {TITLE} deleted!'), $pageConfig ); return $this->_pageList(); } $this->_loadTemplates( 'page_delete' ); $this->_tmpl->addVars( 'wbAdminApp_SiteMaker', $pageConfig ); return true; } /** * didsplay page editor - copy page definition * * @access private * @param string $pageName name of the page to be displayed * @param array $pageConfig setting if the page * @return boolean true on success */ function _pageCopy( $path ) { $type = 'Standard'; if( !empty( $path ) ) { $type = array_shift( $path ); } $this->_loadTemplates( 'submit', false ); $this->_loadTemplates( 'formErrors', false ); $params = array( 'template' => 'copy_' . strtolower( $type ), 'template_dir' => $this->_appName, 'base_dir' => wbFactory::getParam( 'systemDir' ) . '/admin/templates', 'datasource' => 'page' ); $form =& wbFactory::singleton( 'patForms', $params ); // add Filer and rules! $trimmer =& patForms::createFilter( 'Trim' ); $filename =& patForms::createRule( 'RegexReplace' ); $filexist =& patForms::createRule( 'CheckFile' ); $filexist->setDirectory( wbFactory::getParam( 'baseDir' ) . '/' . wbFactory::getParam( 'configDir' ) . '/pages' ); $filexist->setFormat( '%s.xml' ); $filexist->setParam( false ); // make name as possible filename $el =& $form->getElementByName( 'name' ); $el->addRule( $filename, PATFORMS_RULE_BEFORE_VALIDATION ); $el->addRule( $filexist, PATFORMS_RULE_BEFORE_VALIDATION ); $form->applyFilter( $trimmer ); if( $this->_request['action'] == 'save' ) { $form->setSubmitted( true ); if( $form->validateForm() ) { $data = $form->getValues(); if( !$this->_checkReload() ) { // copy page $this->_conf->loadConfig( '/pagesStandard/' . $data['src'] . '.xml' ); $page = $this->_conf->getConfigValue( 'page' ); $this->_conf->clearConfigValue(); // manipulate source $page['title'] = $data['title']; $page['brief'] = $data['brief']; // handle placeholders $pattern = array( '{PART}', '{NAME}', '{TITLE}', '{BRIEF}' ); $replace = array( '', $data['name'], $data['title'], $data['brief'] ); foreach( $page['content'] as $part => $cnt ) { $replace[0] = $part; $page['content'][$part]['href'] = str_replace( $pattern, $replace, $cnt['href'] ); if( !isset( $page['content'][$part]['params'] ) ) { continue; } foreach( $page['content'][$part]['params'] as $key => $value ) { $page['content'][$part]['params'][$key] = str_replace( $pattern, $replace, $value ); } } // save new page $this->_conf->setConfigValue( 'page', $page ); $this->_conf->writeConfigFile( '/pages/' . $data['name'] . '.xml' ); $this->_conf->clearConfigValue(); $eData = array( 'src' => $data['src'], 'name' => $data['name'], 'title' => $page['title'], 'brief' => $page['brief'] ); $eLink = array( 'app' => 'SiteMaker/Page/View', 'page' => $data['name'] ); wbEvent::trigger( 'cms:page:copy:standard', _( 'Created standard page "{TITLE}" ({NAME}) from "{SRC}"' ), $eData, $eLink ); wbDebugger::addMsg( 'SiteMaker', 'Copy page "/pagesStandard/' . $data['src'] . '" to "/pages/'. $data['name'] .'"', 'Page' ); } $this->_addMsg( _( 'Created new page "{TITLE}" from source "{SRC}"' ), $data ); return $this->_pageList(); } } $form->renderForm( array( 'template' => 'form', 'errorTemplateContainer' => 'formErrors', 'errorTemplate' => 'formErrors_entry' ) ); return true; } /** * load menu * * @access private * @return boolean $result true on success */ function _loadMenu( ) { // menu already there! if( !empty( $this->_menu ) ) { return true; } $this->_menu = wbMenuTools::getMenu(); if( patErrorManager::isError( $this->_menu ) ) { return $this->_menu; } return true; } /** * save menu * * @access private * @return boolean $result true on success */ function _storeMenu() { if( empty( $this->_request['menu'] ) ) { return false; } $this->_conf =& wbFactory::singleton( 'patConfiguration' ); // empty menu $this->_menu = array(); $menuRaw = explode( '&', $this->_request['menu'] ); foreach( $menuRaw as $raw ) { $path = explode( '/', $raw ); $this->_storeMenuItem( $path, $this->_menu ); } wbMenuTools::setMenu( $this->_menu ); $res = wbMenuTools::saveMenu(); if( patErrorManager::isError( $res ) ) { return $res; } wbDebugger::addMsg( 'SiteMaker', 'Saved ' . count( $menuRaw ) . ' menu items.', 'Menu' ); wbEvent::trigger( 'cms:menu:saved', _( 'Saved site menu' ) ); return true; } /** * store menu item * * recursive function * * @access private * @param array $path path * @param array $menu menu */ function _storeMenuItem( $path, &$menu ) { $page = array_shift( $path ); $found = false; $index = 0; // see, whether page-config is already there for( $i = 0; $i < count( $menu ); ++$i ) { $index = $i; if( isset( $menu[$i]['page'] ) && ( $menu[$i]['page'] == $page ) ) { $found = true; break; } } // add page config if( !$found ) { $index = count( $menu ); $this->_conf->loadConfig( 'pages/' . $page . '.xml' ); $conf = $this->_conf->getConfigValue( 'page' ); $this->_conf->clearConfigValue(); $menu[$index]['page'] = $page; $menu[$index]['title'] = $conf['title']; $menu[$index]['brief'] = $conf['brief']; } // end of recursion if( empty( $path ) ) { return true; } // create new submenu if( !isset( $menu[$index]['menu'] ) ) { $menu[$index]['menu'] = array(); } return $this->_storeMenuItem( $path, $menu[$index]['menu'] ); } /** * update page data * * @access private * @param string $page name page name * @param array $data new page data * @return string $page name */ function _storePage( $page, $data ) { $new = false; if( $page == 'new' ) { $new = true; } $pageNew = $page; if( isset( $data['name'] ) ) { $pageNew = $data['name']; unset( $data['name'] ); } // create empty page config $conf = array(); $conf['page'] = array(); $conf['page']['edit'] = true; $conf['page']['delete'] = true; // fill with basic data $keys = array( 'title', 'brief' ); foreach( $keys as $key ) { if( !isset( $data[$key] ) ) { continue; } $conf['page'][$key] = $data[$key]; } // remove old page file: if( $page != '_new' && $pageNew != $page ) { $confDir = wbFactory::getParam( 'baseDir' ) . '/' . wbFactory::getParam( 'configDir' ); unlink( $confDir . '/pages/' . $page . '.xml' ); } // translate form data to content configuration $conf['page']['content'] = array(); foreach( $this->_config['page'] as $part => $actions ) { // does not allow to configure any action if( empty( $actions ) ) { continue; } // use default content if( $data['part_' . $part . '_default'] == 'yes' ) { unset( $conf['page']['content'][$part] ); continue; } // get action if( !isset( $data['part_' . $part . '_action'] ) || !in_array( $data['part_' . $part . '_action'], $actions ) ) { patErrorManager::raiseNotice( 'wbAdminApp:SiteMaker:3', 'Invalid action in page configuration', 'Part "'.$part.'" wants to use action "'.$data['part_' . $part . '_action'].'" which is not allowed by site configuration' ); continue; } $action = $data['part_' . $part . '_action']; // store action and href $conf['page']['content'][$part] = array( 'action' => $action, 'href' => $data['part_' . $part . '_' . $action . '_href'], 'params' => array() ); // adjust href considering cmsHtml auto-value if( isset( $data['part_' . $part . '_' . $action . '_auto'] ) && $data['part_' . $part . '_' . $action . '_auto'] == 'yes' ) { $conf['page']['content'][$part]['href'] = $pageNew . '_' . $part; } // add optional parameter... $paramData = array(); if( isset( $data['part_' . $part . '_' . $action . '_params'] ) ) { $paramData = trim( $data['part_' . $part . '_' . $action . '_params'] ); $paramData = explode( "\n", $paramData ); } if( !empty( $paramData ) ) { $params = array(); foreach( $paramData as $pd ) { $pd = trim( $pd ); list( $key, $value ) = explode( '=', $pd, 2 ); $params[$key] = $value; } $conf['page']['content'][$part]['params'] = $params; } else { unset( $conf['page']['content'][$part]['params'] ); } } // add authorisation configuration $conf['page']['auth'] = array(); if( isset( $data['auth_module'] ) && !empty( $data['auth_module'] ) ) { $conf['page']['auth']['module'] = $data['auth_module']; // add authorisation parameter $conf['page']['auth']['param'] = ''; if( isset( $data['auth_param'] ) && !empty( $data['auth_param'] ) ) { $conf['page']['auth']['param'] = $data['auth_param']; } } // transport to patConfiguration $this->_conf->clearConfigValue(); foreach( $conf as $key => $value ) { $this->_conf->setConfigValue( $key, $value ); } $this->_conf->writeConfigFile( '/pages/' . $pageNew . '.xml' ); $this->_conf->clearConfigValue(); wbDebugger::addMsg( 'SiteMaker', 'Save page "' . $pageNew . '"', 'Page' ); wbDebugger::addMsg( 'SiteMaker', wbDebugger::sprint_r( $conf ), 'Config' ); // trigger event $eCode = 'cms:page:saved'; $eMsg = _( 'Saved page "{TITLE}" ({NAME})' ); $eData = array( 'name' => $pageNew, 'title' => $conf['page']['title'], 'brief' => $conf['page']['brief'] ); $eLink = array( 'app' => 'SiteMaker/Page/View', 'page' => $pageNew ); if( $new ) { $eCode = 'cms:page:saved:new'; $eMsg = _( 'Saved new page "{TITLE}" ({NAME})' ); } wbEvent::trigger( $eCode, $eMsg, $eData, $eLink ); return $page; } /** * load and recieve page config * * @access private * @param string $page name page name * @return array $page config values of page or patError on error */ function _getPage( $page ) { $res = $this->_conf->loadConfig( '/pages/' . $page . '.xml' ); if( patErrorManager::isError( $res ) ) { return $res; } $conf = $this->_conf->getConfigValue(); $this->_conf->clearConfigValue(); $page = $conf['page']; unset( $conf['page'] ); foreach( $conf as $key => $value ) { $page['global_' . $key] = $value; } return $page; } /** * load list of pages * * load all page config files and store all pages in $_pages * * @access private * @return boolean $result true on success * @see $_pages */ function _loadPageList() { $this->_pages = array(); // open config folder $pageDir = wbFactory::getParam( 'baseDir' ) . '/' . wbFactory::getParam( 'configDir' ) . '/pages'; $dh = dir( $pageDir ); if( !$dh ) { patErrorManager::raiseError( 'wbAdminApp:SiteMaker:1', 'Failed to get list of pages', 'Could not open configuration folder: "'. $pageDir .'"' ); } while( false !== ( $entry = $dh->read() ) ) { if( $entry[0] == '.' || is_dir( $pageDir . '/' . $entry ) ) { continue; } list( $page, $ext ) = explode( '.', $entry ); if( $ext !== 'xml' ) { patErrorManager::raiseNotice( 'wbAdminApp:SiteMaker:2', 'Unexpected file found!', 'Found file "' . $entry . '"! does not match extension: ".xml"!' ); continue; } // load actual config $this->_conf->loadConfig( '/pages/' . $entry ); $this->_pages[$page] = $this->_conf->getConfigValue( 'page' ); $this->_conf->clearConfigValue(); } wbDebugger::addMsg( 'SiteMaker', 'Found '. count( $this->_pages ) .' pages', 'Page List' ); return true; } /** * didsplay page editor * * @access private * @param array &$basic basic page data (key list) * @param array &$auth authorize config (key list) * @param array &$content content parts data (key list) * @param array &$rules form rules * @return boolean true on success */ function _getPageFormDef( &$basic, &$auth, &$content, &$rules ) { // basic fields: name, title, brief $formDef = array( 'name' => array( 'type' => 'String', 'attributes' => array( 'required' => 'yes', 'display' => 'yes', 'edit' => 'yes', 'label' => _( 'Name' ), 'title' => _( 'Name' ), 'description' => _( 'Unique page identifier. This is for internal use and required to find pages etc.' ), 'maxlength' => '20', 'minlength' => '3', ) ), 'title' => array( 'type' => 'String', 'attributes' => array( 'required' => 'yes', 'display' => 'yes', 'edit' => 'yes', 'label' => _( 'Title' ), 'title' => _( 'Title' ), 'description' => _( 'The title of a page will is shown in the site menu. Therefore it should be short and descriptive.' ), 'maxlength' => '50', 'minlength' => '3', ) ), 'brief' => array( 'type' => 'String', 'attributes' => array( 'required' => 'yes', 'display' => 'yes', 'edit' => 'yes', 'label' => _( 'Description' ), 'title' => _( 'Description' ), 'description' => _( 'The brief description will be visible everywhere next to the title to give the user an additional guid' ), 'maxlength' => '100', 'minlength' => '3', ) ), ); $basic = array_keys( $formDef ); // Authorization module $formDef['auth_module'] = array( 'type' => 'Enum', 'attributes' => array( 'required' => 'no', 'display' => 'yes', 'edit' => 'yes', 'label' => _( 'Authorisation Module' ), 'title' => _( 'Module' ), 'description' => _( 'Authorisation module to be used' ), 'values' => array( array( 'label' => _( '...use globally defined method' ), 'value' => '' ), array( 'label' => _( 'Null - access for everyone' ), 'value' => 'Null' ), array( 'label' => _( 'Anonymous - access for non loged in user' ), 'value' => 'Anonymous' ), array( 'label' => _( 'User - loged in user; optional: specify user(s)' ), 'value' => 'User' ), array( 'label' => _( 'User flag - user must have the specified flag(s)' ), 'value' => 'Userflag' ), array( 'label' => _( 'User Group - user must be in specified group' ), 'value' => 'Group' ) ) ) ); $formDef['auth_param'] = array( 'type' => 'String', 'attributes' => array( 'required' => 'no', 'display' => 'yes', 'edit' => 'yes', 'label' => _( 'Authorisation Parameter' ), 'title' => _( 'Parameter' ), 'description' => _( 'Some authorisation modules require one or more parameter' ), 'maxlength' => '100', ) ); $auth = array( 'auth_module', 'auth_param' ); foreach( $this->_config['page'] as $part => $actions ) { // don't configure parts that are not allowed to! if( empty( $actions ) ) { continue; } $formDef['part_' . $part . '_default'] = array( 'type' => 'Switch', 'attributes' => array( 'required' => 'no', 'display' => 'yes', 'edit' => 'yes', 'label' => ucfirst( $part ) . ' ' . _( 'Default' ), 'title' => 'Default', 'description' => _( 'Use default content for this part' ), 'value' => 'yes', 'class' => 'switch' ) ); $formDef['part_' . $part . '_action'] = array( 'type' => 'Hidden', 'attributes' => array( 'id' => 'part_' . $part . '_action', 'value' => '', ) ); // build form definition for each action foreach( $actions as $action ) { $contentEl = array(); switch( $action ) { case 'cmsHtml': $contentEl = array( 'auto', 'href' ); $formDef['part_' . $part . '_cmsHtml_auto'] = array( 'type' => 'Switch', 'attributes' => array( 'required' => 'no', 'display' => 'yes', 'edit' => 'yes', 'label' => ucfirst( $part ) . '/' . _( 'Auto' ), 'title' => _( 'Auto' ), 'description' => _( 'Select content location automatically...' ), 'value' => 'yes', 'class' => 'switch', 'clicklabel' => 'yes', 'default' => 'yes' ) ); $formDef['part_' . $part . '_cmsHtml_href'] = array( 'type' => 'String', 'attributes' => array( 'required' => 'no', 'display' => 'yes', 'edit' => 'yes', 'label' => ucfirst( $part ) . '/' . _( 'Location' ), 'title' => _( 'Location' ), 'description' => _( '...or type in the content location manually' ), ) ); // add rule $rule =& patForms::createRule( 'ConditionalRequired' ); $rule->addCondition( 'part_' . $part . '_cmsHtml_auto', '' ); $rule->addCondition( 'part_' . $part . '_default', '' ); $rule->setRequiredFields( array( 'part_' . $part . '_cmsHtml_href' ) ); array_push( $rules, $rule ); break; case 'staticString': $contentEl = array( 'href' ); $formDef['part_' . $part . '_staticString_href'] = array( 'type' => 'String', 'attributes' => array( 'required' => 'no', 'display' => 'yes', 'edit' => 'yes', 'label' => ucfirst( $part ) . '/'. _( 'Content' ), 'title' => _( 'Content' ), 'description' => _( 'Content is a simple (static) string - the one entered here!' ), 'maxlength' => '250', 'minlength' => '3', ) ); break; case 'staticTemplate': $dataSrc = wbFactory::singleton( 'wbFormDatasource_StaticTemplate' ); $values = $dataSrc->getValues(); $contentEl = array( 'href' ); $formDef['part_' . $part . '_staticTemplate_href'] = array( 'type' => 'Enum', 'attributes' => array( 'required' => 'no', 'display' => 'yes', 'edit' => 'yes', 'label' => ucfirst( $part ) . '/' . _( 'Template' ), 'title' => _( 'Template' ), 'description' => _( 'The actual content will be loaded from a custom HTML-template' ), 'values' => $values ) ); break; case 'loadModule': $dataSrc = wbFactory::singleton( 'wbFormDatasource_LoadModule' ); $values = $dataSrc->getValues(); $contentEl = array( 'href', 'params' ); $formDef['part_' . $part . '_loadModule_href'] = array( 'type' => 'Enum', 'attributes' => array( 'required' => 'no', 'display' => 'yes', 'edit' => 'yes', 'label' => ucfirst( $part ) . '/' . _( 'Module' ), 'title' => _( 'Module' ), 'description' => _( 'Select a module which builds the content' ), 'values' => $values ) ); $formDef['part_' . $part . '_loadModule_params'] = array( 'type' => 'Text', 'attributes' => array( 'required' => 'no', 'display' => 'yes', 'edit' => 'yes', 'label' => ucfirst( $part ) . '/' . _( 'Parameter' ), 'title' => _( 'Parameter' ), 'description' => _( 'Enter optional module parameter. key=value, one parameter per line' ), 'rows' => 5 ) ); break; case 'loadExtension': $dataSrc = wbFactory::singleton( 'wbFormDatasource_LoadExtension' ); $values = $dataSrc->getValues(); $contentEl = array( 'href', 'params' ); $formDef['part_' . $part . '_loadExtension_href'] = array( 'type' => 'Enum', 'attributes' => array( 'required' => 'no', 'display' => 'yes', 'edit' => 'yes', 'label' => ucfirst( $part ) . '/' . _( 'Extension' ), 'title' => _( 'Extension' ), 'description' => _( 'Select a custom extension which builds the content' ), 'values' => $values ) ); $formDef['part_' . $part . '_loadExtension_params'] = array( 'type' => 'Text', 'attributes' => array( 'required' => 'no', 'display' => 'yes', 'edit' => 'yes', 'label' => ucfirst( $part ) . '/' . _( 'Parameter' ), 'title' => _( 'Parameter' ), 'description' => _( 'Enter optional extension parameter. key=value, one parameter per line' ), 'rows' => 5 ) ); break; } // keep hint if( !isset( $content[$part] ) ) { $content[$part] = array(); } $content[$part][$action] = $contentEl; } } return $formDef; } /** * user function to compare pages by title * * @access private * @return int $result * @see usort() */ function _comparePage( $a, $b ) { return strcasecmp( $a['title'], $b['title'] ); } /** * get form errors from form and translate them to template * * @access private * @param object $form patForm object * @return boolean true */ function _displayFormErrors( &$form ) { $errors = $form->getValidationErrors(); if( empty( $errors ) ) { return true; } $errorRows = array(); foreach( $errors as $elName => $elErrors ) { $row = array(); $el =& $form->getElementByName( $elName ); $atts = $el->getAttributes(); foreach( $atts as $key => $att ) { if( is_array( $att ) ) { continue; } $row['field_'.$key] = $att; } foreach( $elErrors as $err ) { foreach( $err as $key => $value ) { $row['error_' . $key] = $value; } } array_push( $errorRows, $row ); } $this->_tmpl->addRows( 'formErrors_entry', $errorRows ); $this->_tmpl->setAttribute( 'formErrors' , 'visibility', 'visible' ); return true; } } ?>