upload/src/service/design/srv/PwDesignExportZip.php
<?php
/**
 * the last known user to change this file in the repository  <$LastChangedBy: gao.wanggao $>
 * @author $Author: gao.wanggao $ Foxsee@aliyun.com
 * @copyright ?2003-2103 phpwind.com
 * @license http://www.phpwind.com
 * @version $Id: PwDesignExportZip.php 24989 2013-02-28 02:53:30Z gao.wanggao $ 
 * @package 
 */
class PwDesignExportZip {
	protected $dir = '';
	protected $pageid = 0;
	protected $folder = '';
	
	private $_tplExt = '.htm';
	private $_files = array();
	private $_moduleConf = array();
	
	public function __construct($pageBo) {
		$this->pageid = $pageBo->pageid;
		$pageInfo = $pageBo->getPage();
		$this->folder = str_replace('/', '_', $pageInfo['page_router']);
		$this->dir = Wind::getRealDir('THEMES:portal.local.'). $pageBo->getTplPath() . '/';
	}
	
	public function zip($charset = 'utf-8') {
		Wind::import('LIB:utility.PwZip');
		$zip = new PwZip();
		$files = $this->read($this->dir);
		$fromCharset = Wekit::app()->charset;
		foreach ($files AS &$v) {
			$v['filename'] = str_replace($this->dir, '', $v['filename']);
			$ext = strrchr($v['filename'], ".");
			if($ext != $this->_tplExt) continue;
			//$v['data'] = $this->decompilePw($v['data']);
			$v['data'] = $this->decompileTitle($v['data']);
			//$v['data'] = $this->decompileList($v['data']);
			$v['data'] = $this->decompileTpl($v['data']);
			$v['data'] = $this->decompileStyle($v['data']);
		}
		foreach ($files AS $file) {
			if ($file['filename'] == 'module/data.txt') continue;
			if (strtolower($file['filename']) == 'manifest.xml') {
				Wind::import("WIND:parser.WindXmlParser");
				$xml = new WindXmlParser('1.0', $fromCharset);
				$config = $xml->parseXmlStream($file['data'], 0);
				unset($config['module']);
				$file['data'] = $this->xmlFormat($config, $charset);
			} else {
				$ext = strtolower(substr(strrchr($file['filename'], '.'), 1));
				if (in_array($ext, array('css', 'js', 'htm'))) {
					$file['data'] = WindConvert::convert($file['data'], $charset, $fromCharset);
				}
			}
			$file['filename'] = $this->folder.'/'.$file['filename'];
			if (!$zip->addFile($file['data'], $file['filename'])) return new PwError("DESIGN:zlib.error");
		}
		$txt = $this->doTxt($charset);
		$txtfile = $this->folder.'/module/data.txt';
		$zip->addFile($txt['content'], $txtfile);
		return $zip->getCompressedFile();
	}
	
	protected function decompileTitle($section) {
		if (preg_match_all('/\<pw-title\s*id=\"(\w+)\"\s*>/isU',$section, $matches)) {
			foreach ($matches[1] AS $k=>$v) {
				if (!$v) continue;
	    		$section = str_replace($matches[0][$k], '<pw-title>', $section);
    		}
		}
		return $section;
	}
	
	/*protected function decompileList($section) {
		Wind::import("SRV:design.bo.PwDesignModuleBo");
		if (preg_match_all('/\<pw-list\s*id=\"(\d+)\"\s*>/isU',$section, $matches)) {
			foreach ($matches[1] AS $k=>$v) {
				if (!$v) continue;
				$section = str_replace($matches[0][$k], '<pw-list role="'.$v.'">', $section);
    		}
		}
		return $section;
	}*/
	
	
	protected function decompileTpl($section) {
		Wind::import("SRV:design.bo.PwDesignModuleBo");
		if(preg_match_all('/\<design\s*id=\"*D_mod_(\d+)\"*\s*role=\"*module\"*\s*[>|\/>]<\/design>/isU', $section, $matches)) {	
			foreach ($matches[1] AS $k=>$v) {
				$bo = new PwDesignModuleBo($v);
				$module = $bo->getModule();
				$property = $bo->getView();
				$_html = '<pw-list id="'.$k.'">';
				$_html .= $bo->getTemplate();
				$_html .= '</pw-list>';
				$section = str_replace($matches[0][$k], $_html, $section);
				$this->_moduleConf[$k] = array(
					'itemid'=>$k,
					'name'=>$module['module_name'],
					'model'=>$bo->getModel(), 
					'id'=>$v,
					'titlenum'=>strval($property['titlenum']),
					'desnum'=>strval($property['desnum']),
					'timefmt'=>$property['timefmt'],
					'limit'=>strval($property['limit']));
			}
		}
		return $section;
	}
	
	/*
	protected function decompilePw($section) {
		$in = array(
			'<design role="start"/>',
			'<!--# if($portal[\'header\']){ #--><template source=\'TPL:common.header\' load=\'true\' /><!--# } #-->',
			'<!--# if($portal[\'navigate\']){ #--><div class="bread_crumb">{@$headguide|html}</div><!--# } #-->',
			'<!--# if($portal[\'footer\']){ #--><template source=\'TPL:common.footer\' load=\'true\' /><!--# } #-->',
			'<design role="end"/>',
		);
		$out = array(
			'<pw-start/>',
			'<pw-head/>',
			'<pw-navigate/>',
			'<pw-footer/>',
			'<pw-end/>',
		);
		return str_replace($in, $out, $section);
	}

	protected function decompileSegment($section) {
		$segment = $this->_getSegmentDs()->getSegmentByPageid($this->pageid);
		if(preg_match_all('/\<design\s*role=\"segment\"\s*id=\"(.+)\"[^>]+>/isU', $section, $matches)) {
			foreach ($matches[1] AS $k=>$v) {
				if (!$v) continue;
				if (isset($segment[$v])) {
					$section = str_replace($matches[0][$k], $segment[$v]['segment_struct'], $section);
				} else {
					$section = str_replace($matches[0][$k], '<pw-drag/>', $section);
				}
			}
		}
		return $section;
	}
	
	protected function decompileStruct($section) {
		$ds = Wekit::load('design.PwDesignStructure');
		if(preg_match_all('/\<design\s*role=\"title\"\s*id=\"(.+)\"[^>]+>/isU', $section, $matches)) {
			foreach ($matches[1] AS $k=>$v) {
				if (!$v) continue;
				$struct = $ds->getStruct($v);
				$_html = '<pw-title>';
				$_html .= unserialize($struct['struct_title']);
				$_html .= '</pw-title>';
				$section = str_replace($matches[0][$k], $_html, $section);
			}
		}
		return $section;
	}*/

	protected function decompileStyle($section) {
		$in = '/["|\']{\@G\:design\.url\.css}\/style\.css\?rand\=(\d+)["|\']/U';
		$out = '"{@G:design.url.css}/style.css"';
		return preg_replace($in, $out, $section);
	}
	
	protected function read($dir) {
		if (!is_dir($dir)) return array();
		if (!$handle = @opendir($dir)) return array();
		while (false !== ($file = @readdir($handle))) {
			if ('.' === $file || '..' === $file) continue;
			$fileName = $dir . $file;
			if (is_file($fileName)){
				if (!$_handle = fopen($fileName, 'rb')) continue;
				$data = '';
				while (!feof($_handle))
					$data .= fgets($_handle, 4096);
				fclose($_handle);
				$this->_files[] = array('filename'=>$fileName, 'data'=>$data);
			}elseif (is_dir($fileName . '/')) {
				$this->read($fileName. '/');
			}
		}
		unset($data);
		@closedir($handle);
		return $this->_files;
	}
	
	protected function doTxt($charset = 'utf-8') {
		$pageInfo = $this->_getPageDs()->getPage($this->pageid);
		Wind::import('SRV:design.srv.PwDesignExportTxt');
		$srv = new PwDesignExportTxt($pageInfo);
		return $srv->txt($charset);
	}
	
	protected function xmlFormat($array, $charset = 'utf-8') {
		$array['application']['charset'] = $charset;
    	$dom = new DOMDocument('1.0', $charset);
        $root = $dom->createElement('manifest');
        $dom->appendChild($root);
        $this->_creatDom($root, $dom, $array);
		return $dom->saveXML();	
	}
	
	private function _creatDom($root, $dom, $array) {
		foreach ($array AS $k=>$v) {
			if (is_numeric($k)) {
				$child = $dom->createElement('item');
			} else {
				$child = $dom->createElement($k);
			}
			$root->appendChild($child);
			if (!is_array($v)){
				$child->appendChild($dom->createTextNode($v));
			} else {
				$this->_creatDom($child, $dom, $v);
			}
		}
	}
	
	private function _getSegmentDs() {
		return Wekit::load('design.PwDesignSegment');
	}
	
	private function _getPageDs() {
		return Wekit::load('design.PwDesignPage');
	}
}
?>