<?php
/*
 * 站点导航帮助
 * 基于Yii框架应用.
 */
class Helper
{
    public static function guid()
    {
        mt_srand((double)microtime()*10000);//optional for php 4.2.0 and up.
        $charid = strtoupper(md5(uniqid(rand(), true)));
        $hyphen = chr(45);// "-"
        $uuid = substr($charid, 0, 8).$hyphen
            .substr($charid, 8, 4).$hyphen
            .substr($charid,12, 4).$hyphen
            .substr($charid,16, 4).$hyphen
            .substr($charid,20,12);

        return $uuid;
    }
    
    /**
     * 构造一个可用的$criteria变量
     * @param CDbCriteria $criteria
     * @param array $params
     * @return CDbCriteria
     */
    public static function buildCriteria(CDbCriteria $criteria, $params)
    {
        // 首先将分页跟排序的变量删掉
        $pagination = new CPagination();
        $pageVar = $pagination->pageVar;

        $sort = new CSort();
        $sortVar = $sort->sortVar;

        unset($params[$pageVar], $params[$sortVar], $params['r']);

        if (empty($params))
        {
            return $criteria;
        }

        foreach ($params as $key => $value)
        {
            if (!is_array($value))
            {
                continue;
            }

            // 由于浏览器自动将‘.’替换成‘_’，关联的查询会有问题，所以用-代替‘.’，在这里替换回去
            $tmpKey = str_replace('-', '.', $key);

            // 处理范围
            if (!isset($value['operate']) && !empty($value['value']))
            {
                // 处理时间段的问题，默认时间段字段前面都加上begintime_、endtime_标明是时间段
                if (preg_match('/TimeBegin/i', $tmpKey))
                {
                    $criteria->compare(str_replace('TimeBegin_', '', $tmpKey), ">={$value['value']} 00:00:00");
                }

                if (preg_match('/TimeEnd/i', $tmpKey))
                {
                    $criteria->compare(str_replace('TimeEnd_', '', $tmpKey), "<={$value['value']} 23:59:59");
                }
                // end

                if (preg_match('/RangeStart/i', $tmpKey))
                {
                    $criteria->compare(str_replace('RangeStart_', '', $tmpKey), ">={$value[value]}");
                }

                if (preg_match('/RangeEnd/i', $tmpKey))
                {
                    $criteria->compare(str_replace('RangeEnd_', '', $tmpKey), "<={$value[value]}");
                }

                // 完了直接返回，后面的不再执行
                continue;
            }

            // TODO 暂时缺少in方法，以后补上-___-
            if (6 == $value['operate'])
            {
                $criteria->addSearchCondition($tmpKey, $value['value']);
            }
            else
            {
                /**
                 * 利用compare()方法组合出一个特殊的条件
                 * 例如：id > 1 或者 id < 1
                 */
                $opreate = Operate::$_operations[$value['operate']];
                $criteria->compare($tmpKey, $opreate['operate'] . $value['value']);
            }
        }

        //print_r($criteria);die;
        return $criteria;
    }
    
    public static function arrayFlipKeys($arr)
    {
    	$arr2 = array();
    	$arrkeys = array_keys($arr);
    	list(, $first) = each(array_slice($arr, 0, 1));
    	if($first)
    	{
    		foreach($first as $k=>$v)
    		{
    			foreach($arrkeys as $key)
    			{
    				$arr2[$k][$key] = $arr[$key][$k];
    			}
    		}
    	}
    	return $arr2;
    }

    /**
	 * 获得所有部门列表
     * 通过模块来动态获取部门列表.每个模块中有对应的name和cn_name.
	 * @return array('name'=>部门名,'cn_name'=>部门中文名)
	 */
	public static function getAllDepartments()
	{
		# $filter用于过滤掉非部门模块.
		$filter = array(
            'gii',
            'site',
        );
		$data = array();

        # 获取Yii加载的模块
		$modules = Yii::app()->getModules();
		if (!empty($modules))
		{
			foreach ($modules as $name => $module)
			{
				if (!in_array($name, $filter))
				{
					$tmp['cn_name'] = $module['cn_name'];
					$tmp['name'] = $name;
					$data[] = $tmp;
				}
			}
		}

		return $data;
	}
    
    /**
     * 得到所有的M_C_A信息
     * array('module name'=>array('controller name'=>array('all actions'))))
     * @return array
     */
    public static function getAllModulesInfo()
    {
        $modules=array();
        $departments = Helper::getAllDepartments();
		foreach ($departments as $department)
		{
			$module = Helper::findModule($department['name']);
			$actions = array();
			if (!empty($module))
			{
				$controllers = Helper::scanModuleDir($module->controllerPath);
				if (!empty($controllers))
				{
					foreach ($controllers as $controller)
					{
						$controllerFile = $module->controllerPath . DS . $controller . '.php';
						$controller = str_replace('Controller', '', $controller);
						$actions[strtolower($controller)] = Helper::getAllActions($controllerFile);
					}
					$modules[$department['name']] = $actions;
                   // $modules[$department['name']]['cn_name'] = $department['cn_name'];
				}
			}
		}
        return $modules;
    }

    /**
	 * 按名字返回一个模块
	 * @param string $moduleID
	 * @return mixed null|CModule
	 */
	public static function findModule($moduleId)
	{
		if (Yii::app()->getModule($moduleId))
		{
			return Yii::app()->getModule($moduleId);
		}

        #如果父模块不存在,则查找子模块.
		$modules = Yii::app()->getModules();
		foreach ($modules as $mod => $conf)
		{
			if (Yii::app()->getModule($mod))
			{
				return Helper::_findInModule(Yii::app()->getModule($mod), $moduleId);
			}
		}
		return null;
	}

    /**
	 * 查找一个子模块
	 * @param CModule $parent
	 * @param string $moduleId
	 * @return mixed null|CModule
	 */
	private static function _findInModule($parent, $moduleId)
	{
		if ($parent->getModule($moduleId))
		{
			return $parent->getModule($moduleId);
		}
		else
		{
			$modules = $parent->getModules();
			foreach ($modules as $mod => $conf)
			{
				return self::_findInModule($parent->getModule($mod), $moduleId);
			}
		}
		return null;
	}

    /**
	 * 扫描一个module的controller目录，返回所有controller
	 * @param CModule $module
	 * @return array
	 */
	public static function scanModuleDir($path)
	{
		$dirObj = new DirectoryIterator($path);
		foreach ($dirObj as $dir)
		{
			if ($dir->isFile() && false !== strpos($dir->getFilename(), 'Controller'))
			{
				//$controller = explode('.', $dir->getFilename());
				//$controllers[] = $controller[0];
                $controllers[] = $dir->getBasename('.php');
			}
		}
		return $controllers;
	}

    /**
	 * 获取一个controller内所有能外部被访问到的action
	 * 注：当前假设不使用yii的actions功能
	 * @param string $controller
	 * @param string $module
	 * @return array
	 */
	public static function getAllActions($controller, $module = 'default')
	{
		if (!is_file($controller))
		{
			return false;
		}

        #读取Controller里定义的Action开始,如:function actionList()将被读取为list.
		$content = file_get_contents($controller);
		preg_match_all('/function\saction(\w+)\(\)/i', $content, $action);
		$actions = $action[1];

		# 过滤掉actions()这个方法
		if (!empty($actions))
		{
			foreach ($actions as $key => &$value)
			{
				if ('s' == $value)
				{
					unset($actions[$key]);
				}
			}
		}
        #读取Controller里定义的Action结束

        #读取Controller外部定义的Action开始
		preg_match_all('\'(\w+)Action\'', $content, $matchs);
		if (!empty($matchs[1]))
		{
			foreach ($matchs[1] as $match)
			{
				$a = ucfirst(array_pop(explode('.', $match)));
				if (!in_array($a, $actions))
				{
					$actions[] = preg_replace('/(Action)$/i', '', $a);
				}
			}
		}
		#读取Controller外部定义的Action结束.
        foreach($actions as $key => $value)
        {
            if(substr_count($value,'_')>0)
            {
                unset($actions[$key]);
            }
        }

		return $actions;
	}
}