* @copyright 2004 by http://wombat.exit0.net * @package wombatSite * @subpackage cm */ /** * * * @version 0.2 * @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; /** * 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'; $this->_tmpl =& wbFactory::singleton( 'patTemplate' ); } /** * Constructor for PHP 4 * @access public */ function wbContentManager() { $this->__construct(); } /** * get draft * * set operation mode for getContent * * @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'; } $file = $dir . '/' . str_replace( ' ', '_', $title ) . '.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 ); $this->_resolvFetcher( $content['content'] ); if( $draft ) { wbDebugger::addMsg( 'ContentManager', 'Load draft content for "'. $title .'"', 'Load' ); } else { wbDebugger::addMsg( 'ContentManager', 'Load active content for "'. $title .'"', '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['title'] = $title; $con['content'] = $html; $con['author'] = $author; $con['modified'] = date( 'Y-m-d H:i:s' ); $ser = serialize( $con ); $file = $this->_baseDir . '/' . $this->_contentDir . '/draft/' . str_replace( ' ', '_', $title ) . '.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 ) { $file = str_replace( ' ', '_', $title ) . '.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; } /** * 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 $html; } } ?>