* @copyright 2005 by http://wombat.exit0.net * @package wombatSite * @subpackage cm */ /** * * * @version 1.2.0 * @package wombatSite * @subpackage cm */ class wbContentManager { /** * base directory * @var object $_contentDir */ var $_baseDir = null; /** * content directory * @var object $_contentDir */ var $_contentDir = null; /** * patTemplate object * @var object $tmpl */ var $_tmpl = null; /** * current language to fetch and safe content in * @var string $_lang */ var $_lang = 'C'; /** * defautl language named in configuration file * @var string $_langDefault */ var $_langDefault = 'C'; /** * content fetcher config * * - ns XML-namespace * - tag XML tags * - fetch operation mode toe fetch "xml", "fake" or "process" * * @var array $_cf * @see setFetchmode() */ var $_cf = array( 'ns' => 'cf', 'tag' => 'fetcher', 'fetch' => 'process' ); /** * constructor * @access public */ function __construct() { $this->_baseDir = wbFactory::getParam( 'baseDir' ); $this->_contentDir = wbFactory::getParam( 'varDir' ) . '/content/html'; $conf = wbFactory::getParam( 'config' ); $this->_langDefault = $conf['locale']; $this->_tmpl =& wbFactory::singleton( 'patTemplate' ); } /** * Constructor for PHP 4 * @access public */ function wbContentManager() { $this->__construct(); } /** * set current language * * @access public * @param string $lang * @return boolean $result true on success */ function setLang( $lang ) { $this->_lang = $lang; return true; } /** * select fetchmode * * @access public * @param string $title * @return boolean $result true on success */ function setFetchmode( $mode ) { $modes = array( 'xml', 'fake', 'process' ); if( !in_array( $mode, $modes ) ) { return patErrorManager::raiseError( 'wbContentManager:2', 'Could not set fetchmode', 'Fetchmode must be one of "'. implode( '", "', $modes ) .'"' ); } $this->_cf['fetch'] = $mode; return true; } /** * get draft content * * @access public * @param string $title * @return boolean $result true on success * @see getContent() * @see isDraft() */ function getDraft( $title ) { if( $this->isDraft( $title ) ) { return $this->getContent( $title, true ); } return false; } /** * get content * * @access public * @param string $title * @param boolean $draft get draft content * @return array $content */ function getContent( $title, $draft = false ) { $dir = $this->_baseDir . '/' . $this->_contentDir; if( $draft ) { $dir .= '/draft'; } // check for language specific file(s) $lang = ''; if( $this->_lang != $this->_langDefault ) { $lang = '.' . $this->_lang; $fileLang = $dir . '/' . str_replace( ' ', '_', $title ) . $lang . '.ser'; // create non existing language files! if( !$draft && !file_exists( $fileLang ) ) { $fileOrg = $dir . '/' . str_replace( ' ', '_', $title ) . '.ser'; if( file_exists( $fileOrg ) ) { copy( $fileOrg, $fileLang ); chmod( $fileLang, 0666 ); } } } $file = $dir . '/' . str_replace( ' ', '_', $title ) . $lang . '.ser'; // avoid creating drafts if( !$draft && !file_exists( $file ) ) { $this->saveContent( $title, _( 'Blank page' ), 1 ); $this->activateDraft( $title ); patErrorManager::raiseNotice( 'wbContentManager:1', 'Could not load content - created empty content', 'Could not load HTML content file "' . $file . '"' ); } $ser = file_get_contents( $file ); $content = unserialize( $ser ); if( !isset( $content['lang'] ) && empty( $content['lang'] ) ) { $content['lang'] = $this->_lang; } $this->_resolvFetcher( $content['content'] ); if( $draft ) { wbDebugger::addMsg( 'ContentManager', 'Load draft content for "'. $title .'" Lang: '.$this->_lang.'', 'Load' ); } else { wbDebugger::addMsg( 'ContentManager', 'Load active content for "'. $title .'" Lang: '.$this->_lang.'', 'Load' ); } return $content; } /** * check whether draft draft exists or not * * @access private * @param string $title * @return boolean $result true if there is a draft */ function isDraft( $title ) { $file = $this->_baseDir . '/' . $this->_contentDir . '/draft/' . str_replace( ' ', '_', $title ) . '.ser'; if( file_exists( $file ) ) { return true; } return false; } /** * save new content to draft * * * @access private * @return boolean $result true on success */ function saveContent( $title, $html, $author ) { $this->_fake2cf( $html ); $con = array(); $con['lang'] = $this->_lang; $con['title'] = $title; $con['content'] = $html; $con['author'] = $author; $con['modified'] = date( 'Y-m-d H:i:s' ); $ser = serialize( $con ); $lang = ''; if( $this->_lang != $this->_langDefault ) { $lang = '.' . $this->_lang; } $file = $this->_baseDir . '/' . $this->_contentDir . '/draft/' . str_replace( ' ', '_', $title ) . $lang .'.ser'; $fp = fopen( $file, 'w' ); fwrite( $fp, $ser ); fclose( $fp ); wbDebugger::addMsg( 'ContentManager', 'Save content in "'. $file .'"', 'Save' ); wbDebugger::addMsg( 'ContentManager', htmlspecialchars( $con['content'] ), 'Content' ); return true; } /** * move a draft to the folder of active content * * @access private * @return boolean $result true on success */ function activateDraft( $title ) { $lang = ''; if( $this->_lang != $this->_langDefault ) { $lang = '.' . $this->_lang; } $file = str_replace( ' ', '_', $title ) . $lang .'.ser'; $dir = $this->_baseDir . '/' . $this->_contentDir; $src = $dir . '/draft/' . $file; $des = $dir . '/' . $file; // remove old file if( file_exists( $des ) ) { unlink( $des ); } rename( $src, $des ); wbDebugger::addMsg( 'ContentManager', 'Activated draft for "'. $title .'"', 'Activate' ); return true; } /** * transform content * * @access private * @param string $cData * @return string $cData transformed text */ function transform( $cData, $target = 'fake' ) { if( $target == 'xml' ) { $this->_fake2cf( $cData ); return $cData; } if( $target == 'fake' ) { $this->_runFetcher_fake( $cData ); } else if( $target == 'html' ) { $this->_runFetcher_process( $cData ); } return $cData; } /** * resolv xml tags * * @access private * @param string $html * @return boolean $result true on succes */ function _resolvFetcher( &$html ) { $function = '_runFetcher_' . $this->_cf['fetch']; return $this->$function( $html ); } /** * resolv xml tags to xml * * Fetcher are already in XML format - do nothing! * * @access private * @param string $html * @return boolean $result true on succes */ function _runFetcher_xml( &$html ) { // all done! return true; } /** * resolv xml tags to fake * * @access private * @param string $html * @return boolean $result true on succes */ function _runFetcher_fake( &$html ) { $preg = '/<'. $this->_cf['ns'] .':'. $this->_cf['tag'] .' ([^>]*)\/>/'; if( !preg_match_all( $preg, $html, $match, PREG_SET_ORDER ) ) { // nothing found - all done return true; } $replace = '<%s class="cffake" '. $this->_cf['ns'] .':tag="fake" '. $this->_cf['ns'] .':url="%s" >%s'; for( $i = 0; $i < count( $match ); ++$i ) { preg_match_all( '/(url|type)="([^"]*)"/', $match[$i][1], $atts, PREG_SET_ORDER ); $url = ''; $tag = 'span'; for( $j = 0; $j < count( $atts ); ++$j ) { if( $atts[$j][1] == 'url' ) { $url = $atts[$j][2]; } else if( $atts[$j][1] == 'type' ) { if( $atts[$j][2] == 'block' ) { $tag = 'div'; } } } $html = str_replace( $match[$i][0], sprintf( $replace, $tag, $url, $url, $tag ), $html ); } return true; } /** * resolv xml tags to process * * @access private * @param string $html * @return boolean $result true on succes */ function _runFetcher_process( &$html ) { $preg = '/<'. $this->_cf['ns'] .':'. $this->_cf['tag'] .'/'; $split = preg_split( $preg, $html ); // no fetcher found if( count( $split ) == 1 ) { return true; } $fetcher =& wbFactory::singleton( 'wbContentFetcher' ); $replace = '<'. $this->_cf['ns'] .':'. $this->_cf['tag']; for( $i = 1; $i < count( $split ); ++$i ) { if( !preg_match( '/.*url="([^"]*)"[^(\/>)]*\/>/', $split[$i], $match ) ) { continue; } $cfHtml = $fetcher->fetchHtml( $match[1] ); if( patErrorManager::isError( $cfHtml ) ) { return $cfHtml; } $split[$i] = str_replace( $match[0], $cfHtml, $split[$i] ); } $html = implode( '', $split ); return true; } /** * resolv fake cf:fake tags! * * @access private * @param string $html * @return boolean $result true on success */ function _fake2cf( &$html ) { // search for special attribute in "div" or "span" tags $preg = '/(<(span|div)([^>]+)cf:tag="fake"([^>]*)>)([^<]*)(<\/\\2>)/m'; if( !preg_match_all( $preg, $html, $match, PREG_SET_ORDER ) ) { // nothing to replace return true; } $attr = $this->_cf['ns'] . ':tag="fake"'; $replace = '<' . $this->_cf['ns'] . ':' . $this->_cf['tag'] . ' url="%s" type="%s" />'; for( $i = 0; $i < count( $match ); ++$i ) { $atts = $match[$i][3] . ' ' . $match[$i][4]; preg_match( '/cf:url="([^"]*)"/', $atts, $url ); $type = 'inline'; if( $match[$i][2] == 'div' ) { $type = 'block'; } $html = str_replace( $match[$i][0], sprintf( $replace, $url[1], $type ), $html ); } return true; } } ?>