<?php
/*
* @package LabCMS
* @copyright (c) 2006 Alexander Levin aka Loki (loki_angel@mail.ru)
* @support http://labcms.ru
* @license http://opensource.org/licenses/gpl-license.php GNU Public License
*/

class admin_modules_module extends DefaultObject
{
	protected $allowed_keys=array(
		'module_id', 'module', 'name', 'section', 'depends', 'component', 'static', 'disable', 'runlevel'
	);
	
	public function __construct($id=null)
	{
		$this->data['id']=&$this->data['module_id'];
		if (is_numeric($id)) $this->loadDataById($id);
		elseif($id) $this->loadDataByName($id);
	}
	
	public function getInstalledModules()
	{
		$list=array();
		if ($result=Db::i()->select("SELECT * FROM ?_modules ORDER BY NAME")) {
			foreach ($result as $item) {
				$obj=Factory::create('admin_modules.module');
				$obj->set($item);
				$list[$obj->id]=$obj;
			}
		}
		return $list;
	}
	
	public function getAllModules()
	{
		$all_mods=glob(LAB_PATH_MODULES.'/'."*", GLOB_ONLYDIR);
		$modules=$this->getInstalledModules();
		foreach ($all_mods as $key=>$path) {
			$all_mods[$key]=basename($path);
			foreach ($modules as $module) {
				if ($module->module==$all_mods[$key]) {
					unset($all_mods[$key]);
					break;
				}
			}
		}
		//сейчас в массиве $all_mods остались только не установленные модули
		foreach ($all_mods as $name) {
			if ($info=$this->getModuleInfo($name)) {
				$obj=Factory::create('admin_modules.module');
				$obj->set($info);
				$modules[]=$obj;
			}
		}
		usort($modules, array($this, 'msort'));
		return $modules;
	}
	
	public function loadDataById($id)
	{
		$data=Db::i()->selectRow("SELECT * FROM ?_modules WHERE module_id=?", $id);
		if ($data) {
			$info=$this->getModuleInfo($data['module']);
			$this->set($info);
			$this->set($data);
		}
	}
	
	public function loadDataByName($name)
	{
		if ($info=$this->getModuleInfo($name)) {
			$this->set($info);
			if ($this->module) {
				$data=Db::i()->selectRow("SELECT * FROM ?_modules WHERE module=?", $this->module);
				if ($data) {
					$this->set($data);
				}		
			}
		}
	}
	
	function getModuleInfo($module)
	{
		if (file_exists(LAB_PATH_MODULES.'/'.$module."/config.xml")) {
			$xml = simplexml_load_file(LAB_PATH_MODULES.'/'.$module."/config.xml");
			$info=get_object_vars($xml);
			$info['module']=$module;
			$info['version']=empty($info['version'])?config::get('core.version')
			.'.'.config::get('core.revision'):$info['version'];
			if (isset($info['configs']) && $info['configs']) $info['configs']=$this->_parse_configs($info['configs']);
			if (isset($info['access']) && $info['access']) $info['access']=$this->_parse_access($info['access']);
			return $info;
		}
		else return false;
	}
	
	public function install($data)
	{
		$runlevel=!empty($this->runlevel)?$this->runlevel:($this->component?1000:1500);
		$query=array(	'module'=>$this->module,
						'name'=>$data['name'],
						'component'=>(!empty($this->component) ? 1 : 0),
						'static'=>(!empty($data['static']) ? 1 : 0),
						'runlevel'=>$runlevel,
						'depends'=>(!empty($this->depends)?$this->depends->module:''));
						
		if (file_exists(LAB_PATH_MODULES.'/'.$this->module."/uninstall.sql")) {
			Db::parse_mysql_dump(LAB_PATH_MODULES.'/'.$this->module."/uninstall.sql", false);
		}
		if (file_exists(LAB_PATH_MODULES.'/'.$this->module."/install.sql")) {
			Db::parse_mysql_dump(LAB_PATH_MODULES.'/'.$this->module."/install.sql", false);
		}
		if (!$this->id) $this->id=Db::i()->query("INSERT INTO ?_modules SET ?a", $query);
		//создаем настройки по умолчанию
		$this->_createDeafultSettings();
		return true;
	}
	
	public function toggle()
	{
		$this->update(array('disable'=>$this->disable?0:1));
	}
	
	public function msort($a, $b)
	{
		if (!$a->id && $b->id) return 1;
		if ($a->id && !$b->id) return -1;
		return strcmp($a->name, $b->name);
	}
	
	protected function _parse_access($access)
	{
		$result=array();
		if (!empty($access->permis))
		foreach ($access->permis as $permis) {
			$permis=get_object_vars($permis);
			$result[$permis['name']]=array(	'default'=>isset($permis['default'])?$permis['default']:'',
											'describe'=>isset($permis['describe'])?$permis['describe']:'');
		}
		return $result;
	}
	
	protected function _parse_configs($configs)
	{
		$result=array();
		if (!empty($configs->config))
		foreach ($configs->config as $cfg) {
			$cfg=get_object_vars($cfg);
			$default=isset($cfg['default'])?$cfg['default']:'';
			if ($cfg['type']=='boolean') $default=$default?'да':'нет';
			$result[$cfg['name']]=array(
				'default'=>$default,
				'title'=>isset($cfg['title'])?$cfg['title']:'',
				'describe'=>isset($cfg['describe'])?$cfg['describe']:''
			);
		}
		return $result;
	}
	
	public function delete()
	{
		//если имеются зависимые модули, то удаляем сначала их
		if ($depends=$this->getDependedModules()) {
			foreach ($depends as $depend) {
				$depend->delete();
			}
		}
		if (file_exists(LAB_PATH_MODULES.'/'.$this->module."/uninstall.sql")) {
			Db::parse_mysql_dump(LAB_PATH_MODULES.'/'.$this->module."/uninstall.sql", false);
		}
		Db::i()->query("DELETE FROM ?_includes WHERE module_id=?", $this->id);
		config::cleanModule($this->module);
		Db::i()->query("DELETE FROM ?_modules WHERE module_id=?", $this->id);
	}
	
	public function getDependedModules()
	{
		$result=array();
		if ($depends=Db::i()->selectCol("SELECT module_id FROM ?_modules WHERE depends=?", $this->module)) {
			foreach ($depends as $id) {
				$result[]=Factory::create('admin_modules.module', $id);
			}
		}
		return $result;
	}
	
	public function toArray()
	{
		return $this->data;
	}
	
	public function __set($key, $val)
	{
		if ($key=='depends' && $val && !is_object($val)) {
			$val=Factory::create('admin_modules.module', $val);
		}
		parent::__set($key, $val);
	}
	
	protected function _updateDB(&$data)
	{
		return Db::i()->query("UPDATE ?_modules SET ?a WHERE module_id=?", $data, $this->id);
	}

	protected function _resetItemCache()
	{
	}
	
	protected function _createDeafultSettings()
	{
		if (count($this->configs)) {
			foreach ($this->configs as $name=>$conf) {
				config::save('module.'.$this->module.'.'.$name, $conf['default'], -1);
			}
		}
	}

	public function getEditForm()
	{
		$form = Factory::create('HTML_QuickForm2', '', 'post', array('action'=>''));

		$name=$form->addElement('text', 'name', array('tabindex'=>1), array('label' => 'Название модуля:'));
		$name->addRule('required', 'Название модуля не может быть пустым');
		$form->addElement('checkbox', 'static', array('tabindex'=>2), array('label' => 'Статичный', 'content'=>''));
		$form->addElement('hidden', 'token', array('value'=>User::i()->token));
		$form->addElement('submit', '', array('value'=>'Сохранить', 'tabindex'=>3));

		$form->addDataSource(Factory::create('HTML_QuickForm2_DataSource_Array', $this->data));

		return $form;
	}
}
