<?php

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

require_once XOOPS_ROOT_PATH."/class/template.php";

/**
 * A temporary log class.
 */
class Legacy_ModuleUtilsSimpleLog
{
	var $mFetalErrorFlag = false;
	var $mMessages = array();

	function add($msg)
	{
		$this->mMessages[] = array('type' => 'report', 'message' => $msg);
	}

	function addReport($msg)
	{
		$this->add($msg);
	}
	
	function addWarning($msg)
	{
		$this->mMessages[] = array('type' => 'warning', 'message' => $msg);
	}

	function addError($msg)
	{
		$this->mMessages[] = array('type' => 'error', 'message' => $msg);
		$this->mFetalErrorFlag = true;
	}
	
	function hasError()
	{
		return $this->mFetalErrorFlag;
	}
}

/**
 * This provides static methods for the module installation. Methods of this class 
 * may move to base class of installers. 
 */
class Legacy_ModuleUtils
{
	/**
	 */
	function installTable(&$module, &$log)
	{
		$sqlfileInfo =& $module->getInfo('sqlfile');
		$dirname = $module->getVar('dirname');

		if (!isset($sqlfileInfo[XOOPS_DB_TYPE])) {
			return;
		}
		
		$sqlfile = $sqlfileInfo[XOOPS_DB_TYPE];
		if (!file_exists(XOOPS_MODULE_PATH . "/" . $dirname . "/" . $sqlfile)) {
			$log->addError("SQL file not found at $sqlfile");
			return false;
		}

		require_once XOOPS_ROOT_PATH . "/class/database/sqlutility.php";
		$util =& new sqlutility($module->getVar('dirname'),$sqlfile);

		$root =& XCube_Root::getSingleton();
		$db =& $root->mController->getDB();

		//
		// TODO The following variable exists for rollback, but it is not implemented.
		//
		$createdTables = $util->get_create();;

		foreach ($util->get_sql() as $sql) {
			if (!$db->query($sql)) {
				$log->addError($db->error());
				return;
			}
		}
		
		$log->addReport("*Database table setup finished.*");
	}

	/**
	 *  Insert template to DB.
	 *  This function depends on the structure of Legacy_RenderSystem. We should
	 * move this to another mechanism.
	 *
	 * @param $dirname string
	 * @param $$template string[][]
	 * @param $log Legacy_ModuleUtilsSimpleLog *
	 * @param bool
	 */
	function installTemplate($module, $template, &$log)
	{
		$tplHandler =& xoops_gethandler('tplfile');

		$fileName = trim($template['file']);

		$tpldata = Legacy_ModuleUtils::readTemplateFile($module->getVar('dirname'), $fileName);
		if ($tpldata == false)
			return false;

		//
		// Create template file object, then store it.
		//
		$tplfile =& $tplHandler->create();
		$tplfile->setVar('tpl_refid', $module->getVar('mid'));
		$tplfile->setVar('tpl_lastimpoerted', 0);
		$tplfile->setVar('tpl_lastmodified', time());

		if (preg_match("/\.css$/i", $fileName)) {
			$tplfile->setVar('tpl_type', 'css');
		}
		else {
			$tplfile->setVar('tpl_type', 'module');
		}

		$tplfile->setVar('tpl_source', $tpldata, true);
		$tplfile->setVar('tpl_module', $module->getVar('dirname'));
		$tplfile->setVar('tpl_tplset', 'default');
		$tplfile->setVar('tpl_file', $fileName, true);

		$description = isset($tpl['description']) ? $tpl['description'] : '';
		$tplfile->setVar('tpl_desc', $description, true);
		
		if ($tplHandler->insert($tplfile)) {
			$log->addReport(@sprintf("Template '${fileName}' has been installed."));
		}
		else {
			$log->addError(@sprintf(_MD_A_BASE_ERROR_INSERT_TEMPLATE, $fileName));
			return false;
		}

		return true;
	}
	
	/**
	 * Read template file, return it.
	 *
	 * @return string or false
	 */
	function readTemplateFile($dirname, $fileName, $isblock = false)
	{
		//
		// Load template data
		//
		if ($isblock) {
			$filePath = XOOPS_MODULE_PATH . "/" . $dirname . "/templates/blocks/" . $fileName;
		}
		else {
			$filePath = XOOPS_MODULE_PATH . "/" . $dirname . "/templates/" . $fileName;
		}

		if (!file_exists($filePath) && is_file($filePath))
			return false;

		$lines = file($filePath);
		if ($lines == false) {
			return false;
		}

		$tpldata = "";
		foreach ($lines as $line) {
			//
			// Unify linefeed to "\r\n" 
			//
			$tpldata .= str_replace("\n", "\r\n", str_replace("\r\n", "\n", $line));
		}
		
		return $tpldata;
	}
	
	/**
	 * Create XoopsBlock object by array that is defined in xoops_version, return it.
	 * @param $module XoopsModule
	 * @param $block array
	 * @return XoopsBlock
	 */
	function &createBlockByInfo(&$module, $block)
	{
		$options = isset($block['options']) ? $block['options'] : null;
		$edit_func = isset($block['edit_func']) ? $block['edit_func'] : null;
		$template = isset($block['template']) ? $block['template'] : null;
		$visible = isset($block['visible']) ? $block['visible'] : (isset($block['visible_any']) ? $block['visible_any']: 0);
		$blockHandler =& xoops_gethandler('block');
		$blockObj =& $blockHandler->create();

		$blockObj->setVar('mid', $module->getVar('mid'));
		$blockObj->setVar('options', $options);
		$blockObj->setVar('name', $block['name']);
		$blockObj->setVar('title', $block['name']);
		$blockObj->setVar('block_type', 'M');
		$blockObj->setVar('c_type', 1);
		$blockObj->setVar('isactive', 1);
		$blockObj->setVar('dirname', $module->getVar('dirname'));
		$blockObj->setVar('func_file', $block['file']);
		$blockObj->setVar('show_func', $block['show_func']);
		$blockObj->setVar('edit_func', $edit_func);
		$blockObj->setVar('template', $template);
		$blockObj->setVar('last_modified', time());
		$blockObj->setVar('visible', $visible);

		return $blockObj;
	}

    /**
     * Merge existing block XoopsBlock object and new XoopsBlock object from xoops_verion
     * @param $oldBlock XoopsBlock
     * @param $newBlock XoopsBlock
     * @param $changedFlag bool
     * @return XoopsBlock
     */
	function &mergeBlockObject(&$oldBlock, &$newBlock, &$changedFlag)
    {
        $blockObj =& $oldBlock->xoopsClone();
        $blockObj->unsetNew();
        
		$changedFlag = false;
		$checkValues = array('name', 'func_file', 'show_func', 'edit_func', 'template');
		foreach($checkValues as $checkValue) {
		    if ($newBlock->getVar($checkValue) != $oldBlock->getVar($checkValue)) {
		        $blockObj->setVar($checkValue, $newBlock->getVar($checkValue));
		        $changedFlag |= true;
		    }
		}

		$old_options=explode("|",$oldBlock->getVar('options'));
		$new_options=explode("|",$newBlock->getVar('options'));
		if (count($new_options) > count($old_options)) {
	        $changedFlag |= true;
		    for ($i=count($old_options); $i<count($new_options); $i++) {
		        $old_options[$i] = $old_options[$i];
		    }
		    $blockObj->setVar('options', implode("|", $old_options));
		} else if (count($new_options) < count($old_options)) {
	        $changedFlag |= true;
		    $blockObj->setVar('options', $newBlock->getVar('options'));
		}
		
		return $blockObj;
    }

	/**
	 * This function can receive both new and update.
	 * @param $module XoopsModule
	 * @param $blockObj XoopsBlock
	 * @param $block array
	 * @return bool
	 */
	function installBlock(&$module, &$blockObj, &$block, &$log)
	{
		$isNew = $blockObj->isNew();
		$blockHandler =& xoops_gethandler('block');

        if (!empty($block['show_all_module'])) {
            $autolink = false;
        } else {
            $autolink = true;
        }
		if (!$blockHandler->insert($blockObj, $autolink)) {
			$log->addError("ERROR : Could not install block whose name is " . $blockObj->getVar('name'));

			return false;
		}
		else {
			$log->addReport("block " . $blockObj->getVar('name') . " has been installed");

			$tplHandler =& xoops_gethandler('tplfile');

			if (!Legacy_ModuleUtils::installBlockTemplate($module, $blockObj)) {
				$log->addError("Could not install block template " . $blockObj->getVar('name'));
			}
			
			//
			// Process of a permission.
			//
			if ($isNew) {
                if (!empty($block['show_all_module'])) {
        			$link_sql = "INSERT INTO " . $blockHandler->db->prefix('block_module_link') . " (block_id, module_id) VALUES (".$blockObj->getVar('bid').", 0)";
		        	if (!$blockHandler->db->query($link_sql)) {
       					$log->addWarn("Could not set link with all module " . $blockObj->getVar('name'));
		        	}
    			}
   				$gpermHandler =& xoops_gethandler('groupperm');
   				$bperm =& $gpermHandler->create();
				$bperm->setVar('gperm_itemid', $blockObj->getVar('bid'));
				$bperm->setVar('gperm_name', 'block_read');
				$bperm->setVar('gperm_modid', 1);
				
				if (!empty($block['visible_any'])) {
    				$memberHandler =& xoops_gethandler('member');
    				$groupObjects =& $memberHandler->getGroups();
    				foreach($groupObjects as $group) {
        				$bperm->setVar('gperm_groupid', $group->getVar('groupid'));
        				$bperm->setNew();
        				if (!$gpermHandler->insert($bperm)) {
        					$log->addWarn("Could not set block permission " . $blockObj->getVar('name'));
        				}
        			}
				} else {
				    $root = $root=&XCube_Root::getSingleton();
                    $groups = $root->mController->mXoopsUser->getGroups();
                    foreach ($groups as $mygroup) {
        				$bperm->setVar('gperm_groupid', $mygroup);
        				$bperm->setNew();
        				if (!$gpermHandler->insert($bperm)) {
        					$log->addWarn("Could not set block permission " . $blockObj->getVar('name'));
    				    }
    				}
				}
			}

			return true;
		}
	}
	
	/**
	 * Save the information of block's template specified and the source code of it
	 * to database.
	 * @return bool
	 */
	function installBlockTemplate(&$module, &$block)
	{
		if ($block->get('template') == null) {
			return true;
		}
		
		$tplHandler =& xoops_gethandler('tplfile');

		$criteria =& new CriteriaCompo();
		$criteria->add(new Criteria('tpl_type', 'block'));
		$criteria->add(new Criteria('tpl_tplset', 'default'));
		$criteria->add(new Criteria('tpl_module', $module->getVar('dirname')));
		$criteria->add(new Criteria('tpl_file', $block->getVar('template')));
		$tplfiles =& $tplHandler->getObjects($criteria);

		if (count($tplfiles) > 0) {
			$tplfile =& $tplfiles[0];
		}
		else {
			$tplfile =& $tplHandler->create();
			$tplfile->setVar('tpl_refid', $block->getVar('bid'));
			$tplfile->setVar('tpl_tplset', 'default');
			$tplfile->setVar('tpl_file', $block->getVar('template'));
			$tplfile->setVar('tpl_module', $module->getVar('dirname'));
			$tplfile->setVar('tpl_type', 'block');
			// $tplfile->setVar('tpl_desc', $tpl_desc);
			$tplfile->setVar('tpl_lastimported', 0);
		}
		
		$tplSource = Legacy_ModuleUtils::readTemplateFile($module->getVar('dirname'), $block->getVar('template'), true);
		$tplfile->setVar('tpl_source', $tplSource);
		$tplfile->setVar('tpl_lastmodified', time());

		return $tplHandler->insert($tplfile);
	}

	function insertAllConfigs(&$module, &$log)
	{
		$configInfos = $module->getInfo('config');

		//
		// Insert comment config by old style.
		//
		if ($module->getVar('hascomments') !=0 ) {
			require_once XOOPS_ROOT_PATH . "/include/comment_constants.php";

			$configInfos[] = array('name' => 'com_rule',
			                         'title' => '_CM_COMRULES',
			                         'description' => '',
			                         'formtype' => 'select',
			                         'valuetype' => 'int',
			                         'default' => 1,
			                         'options' => array('_CM_COMNOCOM' => XOOPS_COMMENT_APPROVENONE, '_CM_COMAPPROVEALL' => XOOPS_COMMENT_APPROVEALL, '_CM_COMAPPROVEUSER' => XOOPS_COMMENT_APPROVEUSER, '_CM_COMAPPROVEADMIN' => XOOPS_COMMENT_APPROVEADMIN)
			                   );

			$configInfos[] = array('name' => 'com_anonpost',
			                         'title' => '_CM_COMANONPOST',
			                         'description' => '',
			                         'formtype' => 'yesno',
			                         'valuetype' => 'int',
			                         'default' => 0
			                   );
		}

		// TODO comment
		
		// TODO notification

		$configHandler =& xoops_gethandler('config');

		$count = 0;
		if (is_array($configInfos)) {
			foreach ($configInfos as $configInfo) {
				$config =& $configHandler->createConfig();
	
				$config->setVar('conf_modid', $module->getVar('mid'));
				$config->setVar('conf_catid', 0);
				$config->setVar('conf_name', $configInfo['name']);
				$config->setVar('conf_title', $configInfo['title'], true);
				if (isset($configInfo['description'])) {
					$config->setVar('conf_desc', $configInfo['description'], true);
				}
				$config->setVar('conf_formtype', $configInfo['formtype'], true);
				$config->setVar('conf_valuetype', $configInfo['valuetype'], true);
				$config->setConfValueForInput($configInfo['default'], true);
				$config->setVar('conf_order', $count++);
	
				if (isset($configInfo['options']) && is_array($configInfo['options'])) {
					foreach ($configInfo['options'] as $key => $value) {
						$configOption =& $configHandler->createConfigOption();
						$configOption->setVar('confop_name', $key, true);
						$configOption->setVar('confop_value', $value, true);
						$config->setConfOptions($configOption);
						unset($configOption);
					}
				}
				
				if (!$configHandler->insertConfig($config)) {
					$log->addError("ERROR: Could not insert config " . $configInfo['name']);
				}
				
				unset($config);
			}
		}
	}

	/**
	 * Delete all configs of $module.
	 *
	 * @param $module XoopsModule
	 */
	function deleteAllConfigs(&$module, &$log)
	{
		if ($this->mModule->getVar('hasconfig') == 0) {
			return;
		}

		$configHandler =& xoops_gethandler('config');
		$configs =& $configHandler->getConfigs(new Criteria('conf_modid', $this->mModule->getVar('mid')));

		if (count($configs) == 0) {
			return;
		}

		foreach ($configs as $config) {
			$configHandler->deleteConfig($config);
		}
	}
}

?>