thinkphp关联模型的自动验证(tp3.2)

浏览:2970 发布日期:2014/02/09 分类:技术分享
自己的解决方案是这样的(tp3.2)
修改Model.class.php中的create方法,我是在最后用了自己自定义的一个_after_create方法/**
     * 创建数据对象 但不保存到数据库
     * @access public
     * @param mixed $data 创建数据
     * @param string $type 状态
     * @return mixed
     */
     public function create($data='',$type='') {
        $odata = $data;
        $olink = $this->options['link'];
        // 如果没有传值默认取POST数据
        if(empty($data)) {
            $data   =   I('post.');
        }elseif(is_object($data)){
            $data   =   get_object_vars($data);
        }
        // 验证数据
        if(empty($data) || !is_array($data)) {
            $this->error = L('_DATA_TYPE_INVALID_');
            return false;
        }

        // 状态
        $type = $type?$type:(!empty($data[$this->getPk()])?self::MODEL_UPDATE:self::MODEL_INSERT);

        // 检查字段映射
        if(!empty($this->_map)) {
            foreach ($this->_map as $key=>$val){
                if(isset($data[$key])) {
                    $data[$val] =   $data[$key];
                    unset($data[$key]);
                }
            }
        }

        // 检测提交字段的合法性
        if(isset($this->options['field'])) { // $this->field('field1,field2...')->create()
            $fields =   $this->options['field'];
            unset($this->options['field']);
        }elseif($type == self::MODEL_INSERT && isset($this->insertFields)) {
            $fields =   $this->insertFields;
        }elseif($type == self::MODEL_UPDATE && isset($this->updateFields)) {
            $fields =   $this->updateFields;
        }
        if(isset($fields)) {
            if(is_string($fields)) {
                $fields =   explode(',',$fields);
            }
            // 判断令牌验证字段
            if(C('TOKEN_ON'))   $fields[] = C('TOKEN_NAME');
            foreach ($data as $key=>$val){
                if(!in_array($key,$fields)) {
                    unset($data[$key]);
                }
            }
        }

        // 数据自动验证
        if(!$this->autoValidation($data,$type)) return false;

        // 表单令牌验证
        if(!$this->autoCheckToken($data)) {
            $this->error = L('_TOKEN_ERROR_');
            return false;
        }

        // 验证完成生成数据对象
        if($this->autoCheckFields) { // 开启字段检测 则过滤非法字段数据
            $fields =   $this->getDbFields();
            foreach ($data as $key=>$val){
                if(!in_array($key,$fields)) {
                    unset($data[$key]);
                }elseif(MAGIC_QUOTES_GPC && is_string($val)){
                    $data[$key] =   stripslashes($val);
                }
            }
        }

        // 创建完成对数据进行自动处理
        $this->autoOperation($data,$type);
        // 赋值当前数据对象
        $this->data =   $data;
        if($olink){
            $this->options['link'] = $olink;
            if(!$this->_after_create($odata)) return false;
        } 
        // 返回创建的数据以供其他调用
        return $data;
     }
然后在RelationModel.class.php中添加两个方法,一个是_after_create一个是opcreate    protected function _after_create($data) {
        // 关联更新
        if(!empty($options['link'])){
            return $this->opCreate($data);
        }
            
        return true;
    }
protected function opCreate($data,$name=''){
        $result =   false;
        if(empty($data) && !empty($this->data)){
            $data = $this->data;
        }elseif(!is_array($data)){
            // 数据无效返回
            return false;
        }
        if(!empty($this->_link)) {
            // 遍历关联定义
            foreach($this->_link as $key=>$val) {
                    // 操作制定关联类型
                    $mappingName =  $val['mapping_name']?$val['mapping_name']:$key; // 映射名称
                    if(empty($name) || true === $name || $mappingName == $name || (is_array($name) && in_array($mappingName,$name)) ) {
                        // 操作制定的关联
                        $mappingType = !empty($val['mapping_type'])?$val['mapping_type']:$val;  //  关联类型
                        $mappingClass  = !empty($val['class_name'])?$val['class_name']:$key;            //  关联类名
                        $mappingKey =!empty($val['mapping_key'])? $val['mapping_key'] : $this->getPk(); // 关联键名
                        // 当前数据对象主键值
                        $pk =   $data[$mappingKey];
                        if(strtoupper($mappingClass)==strtoupper($this->name)) {
                            // 自引用关联 获取父键名
                            $mappingFk   =   !empty($val['parent_key'])? $val['parent_key'] : 'parent_id';
                        }else{
                            $mappingFk   =   !empty($val['foreign_key'])?$val['foreign_key']:strtolower($this->name).'_id';     //  关联外键
                        }
                        if(!empty($val['condition'])) {
                            $mappingCondition   =   $val['condition'];
                        }else{
                            $mappingCondition               =   array();
                            $mappingCondition[$mappingFk]   =   $pk;
                        }
                        // 获取关联model对象
                        $model = D($mappingClass);
                        $mappingData    =   isset($data[$mappingName])?$data[$mappingName]:false;
                        if(!empty($mappingData) || $opType == 'DEL') {
                            switch($mappingType) {
                                case self::HAS_ONE:
                                    $mappingData[$mappingFk]    =   $pk;
                                    $result = $model->create($mappingData);
                                    if($model->getError()) {
                                        $this->error = $model->getError();
                                        return false;
                                    }
                                    break;
                                case self::BELONGS_TO:
                                    break;
                                case self::HAS_MANY:
                                    foreach ($mappingData as $val){
                                        $val[$mappingFk]    =   $pk;
                                        $result = $model->create($val);
                                        if($model->getError()) {
                                            $this->error = $model->getError();
                                            return false;
                                        }
                                    }
                                    break;
                                case self::MANY_TO_MANY:
                                    
                                    break;
                            }
                            if (!empty($val['relation_deep'])){
                                $model->opRelation($opType,$mappingData,$val['relation_deep']);
                            }                               
                    }
                }
            }
        }
        return $result;
    }
如何应用的呢?
和原来一样,先create然后add就行了
有任何问题,请大家指正哈O(∩_∩)O
最佳答案
评论( 相关
后面还有条评论,点击查看>>