动态生成适用于像sql的where条件拼接的面板js代码 与 php处理代码 (二)

来源:互联网 发布:百度网盘wifi改为数据 编辑:程序博客网 时间:2024/05/19 00:15

 

 

/*========生成js配置php========*/

/*============主站导入js==========*/


<?php
$tmp = array();

foreach ($fieldName as $key => $val) {
    $tmp[] = "
    {
       tab : '{$key}'
      ,tip:\"{$val[1]}\"
      ,arrs : ['class=\"fieldName \"']  
    }
    ";
}

$tmp = implode(',', $tmp);
echo "
var wheres = [
    {$tmp}
];
";


$tmp = array("{value :'', text : '禁用本条件'}");

foreach ($fieldOperator as $key => $val) {
    $tmp[] = "
    {value :'{$key}', text : '{$val}'}
    ";
}

$tmp = implode(',', $tmp);
echo "
var symbol = [//通用字段比较符
    {$tmp}
];
";

$tmp = array();

foreach ($logicOperator as $key => $val) {
    $tmp[] = "
    {value :'{$key}', text : '{$val}'}
    ";
}

$tmp = implode(',', $tmp);
echo "
var contactOperator = [//通用连结符
    {$tmp}
];
";
?>

 

/*=====配置数组,修改这里即可修改js配置========*/


    private $fieldOperator = array(//字段比较符允许值
        '='=>'等于'
        , '>'=>'大于'
        , '>='=>'大于或等于'
        , '<'=>'小于'
        , '<='=>'小于等于'
        , '!='=>'不等'
        , 'LIKE'=>'包含'
        , 'NOT LIKE'=>'不包含'
        , 'IN'=>'在...里面'
        , 'NOT IN'=>'不在...里面'
        , 'BETWEEN'=>'在..二者之间'
        , 'NOT BETWEEN'=>'不在..二者之间'
        , 'IS NULL'=>'空值'
        , 'IS NOT NULL'=>'非空值'
    );
    private $fieldName = array(//字段中文名对应的表名
            '省市'=>array('c.a', '看注册可选项')
            ,'部门'=>array('c.b', '看注册可选项')
            ,'所属行业'=>array('c.c', '看注册可选项')
            ,'职位'=>array('c.d', '看注册可选项')
            ,'性别'=>array('c.e', '输入男或女')
        );
    private $logicOperator = array(//逻辑连接符
        'OR'=>'或者'
        ,'AND'=>'并且要'
    );

/*==========关系组拼接php代码=======*/

/*
    * 从主站会员库导入
    */
    public function importSite() {
      $this->benchmark->mark('site_start'); //时间标记a

        if (! $this->logined ){          
            if (empty($gid)) return $this->importTip('需要登录', 1, 1);
        }
                
        $whereSql = $this->whereConcatRow();//开始拼接
        
        if (false === $whereSql) {//拼接失败
            return $this->importTip("所有条件无效:", 1, 1);
        }
        
        $this->load->library('zdb_lib');//加载zend db
        $db = $this->zdb_lib->db;
        $runLoop = (int)$this->input->post('runLoop');//上轮处理位移标记
        $perCount = 500;
        $sql = " SELECT u.mail FROM drupal_users AS u LEFT JOIN drupal_cuser AS c ON u.uid=c.uid WHERE $whereSql LIMIT " .($perCount * $runLoop).", {$perCount}" ;
        //$this->importTip($sql);
        $emails = $db->fetchCol($sql);     
          $this->benchmark->mark('site_end');
          $readTime = $this->benchmark->elapsed_time('site_start', 'site_end');
          $this->importTip("移库耗时:{$readTime}秒<br />");
          $this->importTip("查库位移:{$runLoop}");
        
        if (empty($emails)) {//全部处理完成,提示结束
            $this->importRunJs('resetrunLoop()');//重置导入位置
            return $this->importTip("导入结束.", 1, 1);
        }
        
        //$this->importTip(var_export($emails, 1));
        $this->importEmail($emails, $gid);//把本轮获取数据提交给处理方法
        $this->importTip( "<span class=\"error\">请不要操作,程序正在循环回调中,请结束后再操作</span>", 1);//div方法显示php处理结果
        $runLoop++;
        $this->importRunJs("importSiteAuto({$runLoop})");//设置form中回调下轮位置
    }
    
    /*
     * 拼接行条件
     */
    private function whereConcatRow() {
        $where = $this->input->post('where');//前台已经把所有行关系组$_POST数据放到一个where数组key中
        
        if (empty($where) || ! is_array($where)) {//空关系组,不必处理
            $this->importTip('未提供筛选条件<br>');
            return false;
        }
        
        $sql = '';
        $reI = 0;
        
        foreach ($where as $key => $val) {//确定行与行之间关系
            $this->importTip("<br/>拼接行 [".($key+1)."]<br/>");
            $colsSql = $this->whereConcatCol($val['fields']);//得到列sql
            
            if (false === $colsSql) {//列中全禁用,本行关系无效
                $this->importTip('本行条件无效<br>');
                continue;
            }
            
            $reI++;//必须放在这里,有可能上面的语句导致第二个才是第一有效行,不能使用post过来的key检测是否首行关系组,因为可能首行无效
            
            if ($reI > 1) {//非首行条件
                if (array_key_exists($val['logicOperatorRow'], $this->logicOperator)) {//允许的行连接逻辑符
                    $sql .= ' '.$val['logicOperatorRow'];
                }else {//非法逻辑符,默认
                    $sql .= ' AND ';
                }
            }
            
            $sql .= " ( {$colsSql} ) ";
        }
        
        if ('' == $sql) {//拼接无果
            $this->importTip('所有行条件无效<br>');
            return false;
        }
        
        return $sql;
    }
    
    /*
     * 拼接列条件
     */
    private function whereConcatCol($cols) {
        if (empty($cols) || ! is_array($cols)) {//列关系无效
            $this->importTip('本列条件无效<br>');
            return false;
        }
        
        $loop = 0;
        $sql = '';
        
        foreach($cols as $key => $val) {//确定列之间关系连接符
            $fieldSql = $this->whereConcatField($val['fieldName'], $val['fieldOperator'], $val['fieldValue']);//得到列的sql
            
            if (false === $fieldSql) {//操作符不正确,或是做白功
                continue;
            }
            
            $loop++;//有效列才计数,用于确定首列
            
            if ($loop > 1) {//非首个,才加逻辑符                
                if (array_key_exists($val['logicOperatorField'], $this->logicOperator)) {//允许的逻辑符
                    $sql .= ' '.$val['logicOperatorField']. ' ';
                }else {
                    $sql .= ' AND ';
                }
            }
            
            $sql .= " {$fieldSql} ";
        }
        
        if ('' == $sql) {
            $this->importTip('所有列条件无效<br>');
            return false;
        }
                
        return $sql;
    }
    
    /*
     * 拼接字段条件
     */
    private function whereConcatField($field, $operator, $val) {
        $fieldTmp = $field;
        
        if (empty($operator)) {//条件禁用
            $this->importTip("[{$fieldTmp}] 条件被禁用<br>");
            return false;
        }
        
        if (! array_key_exists($field, $this->fieldName) || ! array_key_exists($operator, $this->fieldOperator)) {

//字段代名/或是连接符号非法,丢弃本字段条件
            $this->importTip("[{$fieldTmp}] 条件非法<br>");
            return false;
        }
        
        $field = $this->fieldName[$field][0];//代名转真实表名
        
        switch($operator) {//根据字段比较符拼接,escape自动增加'';
            case '=':
            case '>':
            case '>=':
            case '<':
            case '<=':
            case '!=':
                $sql = " {$field} $operator " .$this->db->escape($val);//自动加'',且按类型转义
                break;
            case 'LIKE':
            case 'NOT LIKE':
                $tmp = trim($val);
                
                if (empty($tmp)) {
                    $this->importTip("[{$fieldTmp}] 条件 [包含(LIKE)] 比较符不允许空白值<BR/>");
                    return false;//不允许空白值
                }
                
                $sql = " {$field} $operator '%" .$this->db->escape_like_str($val). "%'";//过滤%_号
                break;
            case 'IN':
            case 'NOT IN':
                if (empty($val)) {
                    $this->importTip("[{$fieldTmp}] 条件 [在...之中(IN)] 比较符不允许空值<br/>");
                    return false;//不允许空值
                }
                
                $val = preg_split("/[\n\r]+/", $val);//按行分割成集合中子值,如果需要用到换行符,可以用字符组代替
                
                foreach ($val as $key => $tmp) {//安全过滤
                    $val[$key] = $this->db->escape($tmp);
                }
                
                $val = implode(',', $val);
                $sql = " {$field} $operator ( $val ) ";
                break;
            case 'BETWEEN':
            case 'NOT BETWEEN':
                if (empty($val)) {
                    $this->importTip("[{$fieldTmp}] 条件 [在...之间(BETWEEN)] 比较符不允许空值<br/>");
                    return false;//不允许空值
                }
                
                $val = preg_split("/[\n\r]+/", $val, 2);//按行分割成集合中子值,只取前二个
                
                if (count($val) != 2) {
                    $this->importTip("[{$fieldTmp}] 条件 [在...之间(BETWEEN)] 比较符必须出现一对值<br/>");
                    return false;//必须有二个值
                }
                
                foreach ($val as $key => $tmp) {//转义
                    $val[$key] = $this->db->escape($tmp);
                }
                
                $val = implode(' AND ', $val);
                $sql = " {$field} $operator " .$this->db->escape($val);//自动加'',且按类型转义
                break;
            case 'IS NULL':
            case 'IS NOT NULL':
                $sql = " {$field} $operator ";//不需要字段值
                break;
            default:
                $this->importTip("[{$fieldTmp}] 条件 [{$operator}] 操作符未做拼接规则指定,忽略此条件.<br/>");
                return false;
        }
        
        return $sql;
    }

 


    
    /*
     * 提示
     * out真时输出,否缓存
     * end真时取消loading动画
     */
    private function importTip($tip, $out = 0, $end = 0){
        $tip .= "<br/>";
        
        if (empty($this->importReturn)) {
            $this->importReturn = $tip;
        }else {
            $this->importReturn .= $tip;//缓存提示
        }
        
        if ($out) {//要求输出
            $this->importRunJs("importReturn('" .rawurlencode($this->importReturn). "', {$end})");//为了方便处理,直接编码,在前台再解码
        }
    }
   

/* 在框架中运行父框js,因为回调使用了iframe而不是ajax*/
    private function importRunJs($func){      
      echo "<script>parent.{$func};</script>";
    }