<?php

if (!defined('XOOPS_ROOT_PATH')) exit();

require_once XOOPS_BASE_PATH."/admin/class/AbstractModuleInstaller.class.php";

class Legacy_ModuleUpdater extends Legacy_AbstractModuleInstaller
{
	var $mPreVersion = 0;

	function Legacy_ModuleUpdater($dirname)
	{
		parent::Legacy_AbstractModuleInstaller($dirname);
		
		$this->mProcessScript->register('Legacy_ModuleUpdater.ProcessScript');
		$this->mProcessScript->add(array(&$this, '_processScript'));
		
		$this->mInstallTable->register('Legacy_ModuleUpdater.InstallTable');

		$this->mInstallTemplate->register('Legacy_ModuleUpdater.InstallTemplate');
		$this->mInstallTemplate->add('Legacy_ModuleUpdater::_uninstallTemplate');
	}

	/**
	 * @return bool
	 */
	function execute()
	{
		$this->mLog->addReport(_AD_BASE_MESSAGE_UPDATE_STARTED);
		
		parent::execute();
	}
	
	/**
	 * Load xoops module object installed and return it.
	 * @static
	 * @access public
	 * @param $dirname string
	 * @return XoopsModule
	 */
	function &loadModuleObject($dirname)
	{
		$ret = null;

		$moduleHandler =& xoops_gethandler('module');
		$module =& $moduleHandler->getByDirname($dirname);

		if (!is_object($module))
			return $ret;

		$this->mPreVersion = $module->getVar('version');
        $name = $module->getVar('name','n');
		$module->loadInfoAsVar($dirname);
		$module->setVar('name', $name, true);
		return $module;
	}

	/**
	 * @static
	 */
	function _uninstallTemplate(&$module, &$log)
	{
		$tplHandler =& xoops_gethandler('tplfile');

		//
		// The following processing depends on the structure of Legacy_RenderSystem.
		//
		$tplHandler =& xoops_gethandler('tplfile');
		$delTemplates =& $tplHandler->find('default', 'module', $module->getVar('mid'));
		if(is_array($delTemplates) && count($delTemplates) > 0) {
			//
			// clear cache
			//
			$xoopsTpl=new XoopsTpl();
			$xoopsTpl->clear_cache(null, "mod_" . $module->getVar('dirname'));
			
			foreach ($delTemplates as $tpl) {
				if (!$tplHandler->delete($tpl)) {
					$log->addError(XCube_Utils::formatMessage(_AD_BASE_ERROR_TEMPLATE_UNINSTALLED, $tpl->getVar('tpl_file')));
				}
			}
		}

		//
		// install Template All
		//
		$templates = $module->getInfo('templates');
		if ($templates != false) {
			foreach ($templates as $template) {
				Legacy_ModuleUtils::installTemplate($module, $template, $log);
			}
		}
	}

	/**
	 * @return bool
	 */
	function _installBlock()
	{
		// XoopsBlock[]
		$installBlocks = array();

		// XoopsBlock[]
		$unInstallBlocks = array();

		$definedBlocks = $this->mModule->getInfo('blocks');
		if($definedBlocks == false)
			return false;

		$blockHandler =& xoops_gethandler('block');

		$func_num=0;
		$showfuncs = array();
        $funcfiles = array();
		for ($i=1; $i<= count($definedBlocks); $i++) {
		    $block =&  $definedBlocks[$i];
			$func_num = $i;
		    $showfuncs[]=$block['show_func'];
		    $funcfiles[]=$block['file'];
			$newBlock =& Legacy_ModuleUtils::createBlockByInfo($this->mModule, $block);
			//
			// Get a installed block by mid and name.
			//
			$criteria = new CriteriaCompo();
			$criteria->add(new Criteria('mid', $this->mModule->getVar('mid')));
			$criteria->add(new Criteria('func_num', $func_num));
			$criteria->add(new Criteria('show_func', $block['show_func']));
			$criteria->add(new Criteria('func_file', $block['file']));
			$installedBlocks =& $blockHandler->getObjectsDirectly($criteria);
			//
			// If a installed block is not found, push it to new install block list.
			//
			if (count($installedBlocks) == 0) {
				$newBlock->setVar('func_num', $func_num);
				$installBlocks[] = array($newBlock, $block);
				unset($newBlock);

				continue;
			}

			$changedFlag = false;

			$oldBlock =& $installedBlocks[0];
            $newBlock =& Legacy_ModuleUtils::mergeBlockObject($oldBlock, $newBlock, $changedFlag);

			if ($changedFlag) {
				$installBlocks[] = array($newBlock, $block);
			}
			else {
				if (!Legacy_ModuleUtils::installBlockTemplate($this->mModule, $oldBlock)) {
					$this->mLog->addError("ERROR : Could not update block template ".$oldBlock->getVar('name'));
				}
			}

			unset($newBlock);
			unset($oldBlock);
		}
		$criteria = new CriteriaCompo();
		$criteria->add(new Criteria('mid', $this->mModule->getVar('mid')));
		$installedBlocks =& $blockHandler->getObjectsDirectly($criteria);
		foreach ($installedBlocks as $blockObj) {
            if (!in_array($blockObj->getVar('show_func'), $showfuncs) || !in_array($blockObj->getVar('func_file'), $funcfiles)) {
				$unInstallBlocks[] =& $blockObj;
				unset($blockObj);
            }
        }

		foreach ($installBlocks as $block) {
			Legacy_ModuleUtils::installBlock($this->mModule, $block[0], $block[1], $this->mLog);
		}
        
		foreach ($unInstallBlocks as $block) {
			Legacy_ModuleUtils::unInstallBlock($block, $this->mLog);
		}

	}
	
	function _installPreference()
	{
		Legacy_ModuleUtils::deleteAllConfigs($this->mModule, $this->mLog);
		Legacy_ModuleUtils::insertAllConfigs($this->mModule, $this->mLog);
	}

	function _processScript(&$module, &$log)
	{
		$installScript = trim($module->getInfo('onUpdate'));
		if ($installScript != false) {
			require_once XOOPS_MODULE_PATH . "/" . $module->getVar('dirname') . "/" . $installScript;
			$funcName = 'xoops_module_update_' . $module->getVar('dirname');
			if (function_exists($funcName)) {
				if (!call_user_func($funcName, $module, $this->mPreVersion)) {
					$log->addError("Failed to execute " . $funcName);
				}
			}
		}
	}
	
	function _processReport()
	{
		if (!$this->mLog->hasError()) {
			$this->mLog->add(XCube_Utils::formatMessage(_AD_BASE_MESSAGE_UPDATING_MODULE_SUCCESSFUL, $this->mModule->get('name')));
		}
		else {
			if (is_object($this->mModule)) {
				$this->mLog->addError(XCube_Utils::formatMessage(_AD_BASE_ERROR_UPDATING_MODULE_FAILURE, $this->mModule->get('name')));
			}
			else {
				$this->mLog->addError(XCube_Utils::formatMessage(_AD_BASE_ERROR_UPDATING_MODULE_FAILURE, $this->mDirname));
			}
		}
	}
}

?>