<?php

require_once dirname(dirname(__FILE__)) . '/core/ActionBase.class.php';
require_once dirname(dirname(__FILE__)) . '/XmlItemImport.class.php';
require_once dirname(dirname(dirname(__FILE__))) . '/class/core/Item.class.php';

class Xoonips_ItemImportAction extends Xoonips_ActionBase {

	protected function doInit(&$request, &$response) {
		// init import
		$this->doImport($request, $response);
		$response->setForward('import_success');
		return true;
	}

	protected function doLog(&$request, &$response) {
		// select order
		$import_id = $request->getParameter('import_id');
		if ($import_id) {
			// import log detail
			$this->doLogdetail($request, $response);
			$response->setForward('logdetail_success');
			return true;
		} else {
			// import log
			$this->doLogInit($request, $response);
			$response->setForward('log_success');
			return true;
		}
	}

	private function doImport(&$request, &$response) {
		// token ticket
		$token_ticket = $this->createToken($this->modulePrefix('do_item_import'));

		// get parameter
		$index_select = $request->getParameter('index_select');

		// breadcrumbs
		$breadcrumbs = array(
			array('name' => _MI_XOONIPS_USER_IMPORT_ITEM)
		);

		// select index
		$index_select_arr = array();
		$is['value'] = 'file';
		$is['label'] = _MD_XOONIPS_ITEM_IMPORT_INDEX_SELECT_MSG2;
		$is['selected'] = ($index_select == 'file' ) ? 'yes' : 'no';
		$index_select_arr[] = $is;
		$is['value'] = 'self';
		$is['label'] = _MD_XOONIPS_ITEM_IMPORT_INDEX_SELECT_MSG1;
		$is['selected'] = ($index_select == 'self' ) ? 'yes' : 'no';
		$index_select_arr[] = $is;

		// index tree
		global $xoopsUser;
		$uid = is_object($xoopsUser) ? $xoopsUser->getVar('uid') : XOONIPS_UID_GUEST;
		$indexBean = Xoonips_BeanFactory::getBean('IndexBean', $this->dirname, $this->trustDirname);
		$userBean = Xoonips_BeanFactory::getBean('UsersBean', XCUBE_CORE_USER_MODULE_NAME);
		$is_admin = $userBean->isModerator($uid);
		
		$publicIndex = false;
		$publicGroupIndexes = array();
		$groupIndexes = array();
		$privateIndex = false;
		if ($is_admin) {
			$publicIndex = $indexBean->getPublicIndex();
			$publicGroupIndexes = $indexBean->getPublicGroupIndex();
		}

		if ($uid != XOONIPS_UID_GUEST) {
			$groupIndexes = $indexBean->getGroupIndex($uid);
			$privateIndex = $indexBean->getPrivateIndex($uid);
		}
		$groupIndexes = $indexBean->mergeIndexes($publicGroupIndexes, $groupIndexes);
		$indexes = array();
		$trees = array();
		$url = false;
		// public index
		if ($publicIndex) {
			$indexes[] = $publicIndex;
			$tree = array();
			$tree['index_id'] = $publicIndex['index_id'];
			$tree['html'] = $indexBean->creatIndexTree($publicIndex['index_id'], $url, true, $uid, '_import');
			$trees[] = $tree;
		}
		// group index
		if ($groupIndexes) {
			foreach ($groupIndexes as $index) {
				$indexes[] = $index;
				$tree = array();
				$tree['index_id'] = $index['index_id'];
				$tree['html'] = $indexBean->creatIndexTree($index['index_id'], $url, true, $uid, '_import');
				$trees[] = $tree;
			}
		}
		// private index
		if ($privateIndex) {
			$privateIndex['title'] = 'Private';
			$indexes[] = $privateIndex;
			$tree = array();
			$tree['index_id'] = $privateIndex['index_id'];
			$tree['html'] = $indexBean->creatIndexTree($privateIndex['index_id'], $url, true, $uid, '_import');
			$trees[] = $tree;
		}

		$viewData['xoops_breadcrumbs'] = $breadcrumbs;
		$viewData['token_ticket'] = $token_ticket;
		$viewData['select_tab'] = 1;
		$viewData['index_select_arr'] = $index_select_arr;
		$viewData['index_self'] = ($index_select == 'self' ) ? true : false;
		$viewData['indexes'] = $indexes;
		$viewData['trees'] = $trees;
		$viewData['dirname'] = $this->dirname;
		$response->setViewData($viewData);
	}

	protected function doImportsave(&$request, &$response) {
		// check token ticket
		if (!$this->validateToken($this->modulePrefix('do_item_import'))) {
			return false;
		}

		// get parameter
		$index_select = $request->getParameter('index_select');

		// user info
		global $xoopsUser;
		$uid = is_object($xoopsUser) ? $xoopsUser->getVar('uid') : XOONIPS_UID_GUEST;

		// for self index
		$indexBean = Xoonips_BeanFactory::getBean('IndexBean', $this->dirname, $this->trustDirname);
		$req_indexes = array();
		$my_indexes = null;
		if ($index_select == 'self') {
			$indexes = $indexBean->getIndexAll();
			foreach ($indexes as $index) {
				$index_id = $index['index_id'];
				if ($request->getParameter($this->dirname.'_index_tree_chk_import_'.$index_id)) {
					$req_indexes[] = $index_id;
				}
			}

			if (count($req_indexes) == 0) {
				$viewData['url'] = XOOPS_URL.'/modules/'.$this->dirname.'/itemimport.php';
				$viewData['redirect_msg'] = _AM_XOONIPS_POLICY_ITEMTYPE_IMPORT_FAILURE;
				$response->setViewData($viewData);
				$response->setForward('importsave_success');
				return true;
			}
		} else {
			$my_indexes = array();
			$publicGroupIndexes = array();
			$userBean = Xoonips_BeanFactory::getBean('UsersBean', XCUBE_CORE_USER_MODULE_NAME);
			$is_admin = $userBean->isModerator($uid);
			if ($is_admin) $publicGroupIndexes = $indexBean->getPublicGroupIndex();
			$MyIndexes = $indexBean->mergeIndexes($publicGroupIndexes, $indexBean->getGroupIndex($uid));
			if ($is_admin) $MyIndexes[] = $indexBean->getPublicIndex();
			$MyIndexes[] = $indexBean->getPrivateIndex($uid);
				
			foreach ($MyIndexes as $mindex) {
				$my_indexes[] = $mindex['index_id'];		
				$child_arr = $indexBean->getAllChildIds($mindex['index_id']);
				foreach ($child_arr as $child_id) {
					if (!in_array($child_id, $my_indexes)) {
						$my_indexes[] = $child_id;
					}
				}
			}
		}

		$importfile = $request->getFile( 'import_file' );

		if ( empty( $importfile['name'] ) || $importfile['size'] == 0 ) {
			$viewData['url'] = XOOPS_URL.'/modules/'.$this->dirname.'/itemimport.php';
			$viewData['redirect_msg'] = _AM_XOONIPS_POLICY_ITEMTYPE_IMPORT_FILE_NONE;
			$response->setViewData($viewData);
			$response->setForward('importsave_success');
			return true;
		}

		// check file exists
		if (!file_exists( $importfile['tmp_name'])) {
			die( "don't exist temporary file '".$importfile['tmp_name']."'." );
		}

		// create temporary directry
		$config_bean = Xoonips_BeanFactory::getBean('ConfigBean', $this->dirname, $this->trustDirname);
		$tmp = $config_bean->getConfig('upload_dir');
		$time = date("YmdHis");
		$tmpdir1 = "${tmp}/${time}-im1";
		if (!mkdir($tmpdir1, 0755)) {
			die( "can't create directry '${tmpdir1}'." );
		}
		$tmpdir2 = "${tmp}/${time}-im2";
		if (!mkdir($tmpdir2, 0755)) {
			die( "can't create directry '${tmpdir2}'." );
		}

		// transaction
		$err_chk = false;
		$transaction = Xoonips_Transaction::getInstance();
		$transaction->start();

		// unzip
		system("cd $tmpdir2; unzip -q ".$importfile['tmp_name']);
		$this->flatDirectryInZipFile($tmpdir2, $tmpdir2);

		// Import Log
		$import = array(
		'uid'=>$uid,
		'result'=>0,
		'log'=>"[Import Item] Begin\n",
		'timestamp'=>time(),
		);

		// Import Log
		$import['log'] .= "[Import Item] Zip File : ".$importfile['name']."\n";

		$num = 0;
		$items = array();
		$res_dir = opendir($tmpdir2);
		while (false !== ($itemzip = readdir($res_dir))) {
			if($itemzip == '.' || $itemzip == '..') continue;

			system("cd $tmpdir1; unzip -q ${tmpdir2}/$itemzip");
				
			$itemid = str_replace('.zip','',$itemzip);
			$items[$itemid] = array(
			'xml'=>'',
			'tmpinfo'=>array(),
			'tmpfiles'=>array(),
			'error'=>'',
			);

			$xmlimport = new XmlItemImport();
			$xmlimport->uid($uid);
			$xmlimport->set_db_lang('UTF-8');

			$num++;
			$res_dir2 = opendir($tmpdir1);
			while (false !== ($file = readdir($res_dir2))) {
				if($file == '.' || $file == '..') continue;

				// temp file
				$path = $tmpdir1.'/'.$file;
				if (is_dir($path)) {
					$res_dir3 = opendir($path);
					while (false !== ($tmpfile = readdir($res_dir3))) {
						if($tmpfile == '.' || $tmpfile == '..') continue;
						
						$tmpfile_u = mb_convert_encoding($tmpfile, 'UTF-8', 'SJIS');
						$items[$itemid]['tmpinfo'][] = array(
						'id'=>$file,
						'name'=>$tmpfile_u,
						);
						$items[$itemid]['tmpfiles'][$tmpfile_u] = "${tmpdir1}/${file}/$tmpfile";

						// Import Log
						$import['log'] .= "[Import Item No.${num}] Temp File : ".$tmpfile_u."\n";
					}
					closedir($res_dir3);
				// xml file
				} else {
					$xml_file = $path;
					$items[$itemid]['xml'] = $xml_file;

					// Import Log
					$import['log'] .= "[Import Item No.${num}] XML File : ".$file."\n";

					$fp = fopen($xml_file, 'r');
					$tfp = fopen($xml_file.'.tmp', 'aw');
					while ($line = fgets($fp, 4096)) {
						$line_chk = trim($line);

						// omit index tag
						if ($index_select == 'self' &&
						(preg_match('/^<C:index*/', $line_chk) || preg_match('/^<\/C:index*/', $line_chk))){
							continue;
						}
						fwrite($tfp, $line);

						// Import Log
						$import['log'] .= "$line";
					}
					fclose($fp);
					fclose($tfp);
					unlink($xml_file);
					rename($xml_file.'.tmp', $xml_file);
				}
			}
			closedir($res_dir2);

			// import item
			$xmlimport->set_tmp_file_array($items[$itemid]['tmpfiles']);
			$ret = $xmlimport->xml_import_by_file($items[$itemid]['xml'], $uid, $my_indexes, false);

			if(strlen($tmpdir1) > 4) system("rm -rf ${tmpdir1}/* > /dev/null 2>&1");

			$new_id = $xmlimport->get_create_item_id();
			
			if (!($new_id > 0) || !($ret == '200' || $ret == '206')) {
				$transaction->rollback();

				$items[$itemid]['error'] = $xmlimport->get_err_code();
				$items[$itemid]['err_line'] = $xmlimport->get_line_no();
				$items[$itemid]['err_msg'] = $xmlimport->get_err_msg();
				$err_chk = true;

				// Import Log
				$import['log'] .= "[Import Item No.${num}] Result : Error (Code : ".$items[$itemid]['error'].")\n";
				$import['log'] .= "[Import Item No.${num}] Result : Error (Message : ".$items[$itemid]['err_msg']." [".$items[$itemid]['err_line']."])\n";

				break;

			} elseif ($new_id > 0 && $index_select == 'self') {
				$new_indexes = '';	
				foreach ($req_indexes as $index) {
					$new_indexes .= (strlen($new_indexes) == 0) ? $index : ','.$index;
					// Import Log
					$import['log'] .= "[Import Item No.${num}] Index ID : $index]\n";
				}
							
				$linkBean = Xoonips_BeanFactory::getBean('IndexItemLinkBean', $this->dirname, $this->trustDirname);
				$linkBean->delete($new_id);
				
				if (!$this->forceEditIndex($new_id, $new_indexes)) {
					$transaction->rollback();
					// Import Log
					$import['log'] .= "[Import Item No.${num}] Result : Error (Code : 400)\n";
					$import['log'] .= "[Import Item No.${num}] Result : Error (Message : Couldn't register index.)\n";
					$err_chk = true;
					break;				
				}
			}

			// Import Log
			$import['log'] .= "[Import Item No.${num}] Result : Success (Item ID : $new_id)]\n";
		}
		closedir($res_dir);

		// success
		if (!$err_chk) $transaction->commit();

		// delete temporary
		system("rm -rf $tmpdir1 > /dev/null 2>&1");
		system("rm -rf $tmpdir2 > /dev/null 2>&1");

		// Import Log
		$import['result'] = ($err_chk) ? 0 : 1 ;
		$import['log'] .= "[Import Item] End";
		$import_id = $this->setLogDB($import, $items);

		if ($err_chk) {
			$viewData['url'] = XOOPS_URL.'/modules/'.$this->dirname.'/itemimport.php?op=log&import_id='.$import_id;
			$viewData['redirect_msg'] = _AM_XOONIPS_POLICY_ITEMTYPE_IMPORT_FAILURE;
			$response->setViewData($viewData);
			$response->setForward('importsave_success');
			return true;
		}

		$viewData['url'] = XOOPS_URL.'/modules/'.$this->dirname.'/itemimport.php?op=log&import_id='.$import_id;
		$viewData['redirect_msg'] = _AM_XOONIPS_POLICY_ITEMTYPE_IMPORT_SUCCESS;
		$response->setViewData($viewData);
		$response->setForward('importsave_success');
		return true;
	}

	private function doLogInit( &$request, &$response ){
		// breadcrumbs
		$breadcrumbs = array(
			array('name' => _MI_XOONIPS_USER_IMPORT_ITEM)
		);

		// user info
		global $xoopsUser;
		$uid = is_object($xoopsUser) ? $xoopsUser->getVar('uid') : XOONIPS_UID_GUEST;

		// get item import log
		$logBean = Xoonips_BeanFactory::getBean('ItemImportLogBean', $this->dirname, $this->trustDirname);
		$logs = $logBean->getImportLogByUID($uid);

		foreach ($logs as $key => $log) {
			$logs[$key]['display_time'] = date('Y-m-d H:i:s', $log['timestamp']);

			$items = $logBean->getImportLogItems($log['item_import_log_id']);
			$logs[$key]['items'] = count($items);
		}

		$viewData['xoops_breadcrumbs'] = $breadcrumbs;
		$viewData['select_tab'] = 2;
		$viewData['logs'] = $logs;
		$viewData['dirname'] = $this->dirname;
		$response->setViewData($viewData);
	}

	private function doLogdetail( &$request, &$response ){
		// get parameter
		$import_id = $request->getParameter('import_id');

		// breadcrumbs
		$breadcrumbs = array(
			array(
			    'name' => _MD_XOONIPS_ITEM_IMPORT_LOG_TITLE,
			    'url' => XOOPS_URL.'/modules/'.$this->dirname.'/itemimport.php?op=log'
		  	),
			array(
				'name' => _MD_XOONIPS_ITEM_IMPORT_LOGDETAIL_TITLE
			),
		);

		// get item import log
		$logBean = Xoonips_BeanFactory::getBean('ItemImportLogBean', $this->dirname, $this->trustDirname);
		$import = $logBean->getImportLogInfo($import_id);

		$import['display_time'] = date('Y-m-d H:i:s', $import['timestamp']);

		$items = $logBean->getImportLogItems($import_id);
		$import['items'] = count($items);

		$viewData['xoops_breadcrumbs'] = $breadcrumbs;
		$viewData['select_tab'] = 2;
		$viewData['import'] = $import;
		$viewData['dirname'] = $this->dirname;
		$response->setViewData($viewData);
	}

	private function setLogDB($import, $items){
		$import_id = 0;
		$logBean = Xoonips_BeanFactory::getBean('ItemImportLogBean', $this->dirname, $this->trustDirname);

		$logBean->insert($import);
		$import_id = $logBean->getInsertId();

		if ($import['result'] == 1) {
			foreach ($items as $item_id => $val) {
				$logBean->insertLink($import_id, $item_id);
			}
		}
		return $import_id;
	}

	/**
	 * Force Edit Index
	 *
	 * @param integer $item_id
	 * @param string $checkedIndexes
	 * @return boolean true
	 */
	private function forceEditIndex($itemId, $checkedIndexes) {
		$ret = false;
	
		$certify_msg = '';
		$bean = Xoonips_BeanFactory::getBean('ItemBean', $this->dirname, $this->trustDirname);
		$result = $bean->getItemBasicInfo($itemId);
		$itemtypeId = $result['item_type_id'];
		$item = new Xoonips_Item($itemtypeId, $this->dirname, $this->trustDirname);
		$configBean = Xoonips_BeanFactory::getBean('ConfigBean', $this->dirname, $this->trustDirname);
		$certify = $configBean->getConfig('certify_item');
		$ret = $item->doIndexEdit($itemId, $checkedIndexes, $certify_msg, $certify);
	
		return $ret;
	}

	private function flatDirectryInZipFile($base_dir, $dir) {
		$dir_chk = false;
		$dir_arr = array();
		$o_dir = opendir($dir);
		while (false !== ($name = readdir($o_dir))) {
			if($name == '.' || $name == '..') continue;
			if (stripos($name, '.zip')) {
				rename($dir.'/'.$name, $base_dir.'/'.$name);
			} else {
				$dir_chk = true;
				$dir_arr[] = $name;
			}
		}
		closedir($o_dir);
		if ($dir_chk) {
			foreach ($dir_arr as $name) {
				$next_dir = $dir.'/'.$name;
				$this->flatDirectryInZipFile($base_dir, $next_dir);
				system("rm -rf $next_dir > /dev/null 2>&1");
			}
		}
	}
	
}

