PHPCMS V9 自定义字段原理分析

时间:2022-10-22 11:38:20
这段时间一直在研究phpcms的自定义字段功能。之前听坛里面的朋友说这个功能很强大,很多插件都是基于这个做的,与花了点时间,把这块的功能分析了下,网上关于这方面的资料实在是太少了,都是说在后台怎么操作的,这个我相信用了phpcms的都会操作,但是我要说明的是只在后台简简单单的添加个字段,这是很平常的,并不能显示其中最精髓的部分。这里就大致的分析下。

首先就对原先存在的字段进行分析:就拿modules/content/fields/images这个字段来说明。这个字段文件夹(images)下面的一些文件在这里做简要的说明:

1、config.inc.php:这个文件里面主要是一些初始化的控制信息。对表单中的一些控件设置初始值的;

2、form.inc.php:这个文件主要对该字段在表单中如何显示,以及设置相应的属性和值等的设置;(必)

3、input.inc.php:这个文件主要是对该字段的值在插入数据库之前要进行那些处理的一个函数;(选)

4、ouput.inc.php:这个文件主要是对该字段从数据库取出数据之后,经过这个文件内定义的函数处理之后再显示到页面上;(选)

5、field_add_form.inc.php:这个文件主要是一些html代码,当我们在后台添加字段时,会有选择字段类型的一个下拉框。这个框里面的数据都是通过{mocule}/fields/fields.inc.php文件中获得的。这个里面的数组包括了当前自定义的所有字段值。而每一个字段值都有一个文件夹。这个文件就如同我们上面讲的images,这个下面有很多处理该字段的文件。当我们选择某一个字段类型的时候,会通过json来取这个类型所对应的文件夹下面的field_add_form.inc.php,一次来设置该字段的属性。(必)

6、field_edit_form.inc.php:这个文件的功能和上面的功能基本上是一样的。这个是在编辑字段的时候通过json获取。(必)

在后台添加字段的时候,会根据你的选择,判断是将该字段的值添加到主表(如:news)还是添加到从表(如:news_data),看如下代码(sitemodel_field.php):

//判断添加的字段是选择在主表还是在从表
$tablename = $_POST['issystem'] ? $this->db->db_tablepre.$model_table : $this->db->db_tablepre.$model_table.'_data';

然后按照格式修改那个模型表的字段(添加一个字段,调用add.sql.php文件),之后后现将该字段的所有信息插入到数据表pc_model_field中;

我们先来看下下面这段代码(content.php)

//加载自定义的字段值输出控制类库(对自定义的字段的值的输出进行处理)
require_once CACHE_MODEL_PATH.'content_output.class.php';
$content_output = new content_output($modelid,$catid,$CATEGORYS);
$data = $content_output->get($rs);//对每个字段的值都按需要进行处理,然后在返回进行显示

(content_model.php)

//加载自定义的字段值输入控制类库(对自定义的字段的值的存入DB进行处理)
    require_once CACHE_MODEL_PATH.'content_input.class.php';

(content.php)

$modelid = $category['modelid'];
//取模型ID,依模型ID来生成对应的表单
require CACHE_MODEL_PATH.'content_form.class.php';
$content_form = new content_form($modelid,$catid,$this->categorys);
$forminfos = $content_form->get();

上面的这些都是调用相关处理类的代码;那么这些文件都是怎么得来的呢?里面的内容又是什么呢?这里就要从更新后台缓存说起了。

后台更新缓存(admin/cache_all.php文件)这个文件会调用缓存操作类文件cache_api.class.php文件。我们这里主要来看sitemodel()方法里面的部分代码。

require MODEL_PATH.'fields.inc.php';//返回$fields数组
//更新内容模型类:表单生成、入库、更新、输出
$classtypes = array('form','input','update','output');
//一次从自定义字段文件夹中获取form.inc.php,input.inc.php,update.inc.php,output.inc.php,放到cache_model/**.class.php文件中
foreach($classtypes as $classtype) {
  $cache_data = file_get_contents(MODEL_PATH.'content_'.$classtype.'.class.php');
  $cache_data = str_replace('}?>','',$cache_data);
  //对字段的相关文件夹里面的数据进行处理
  foreach($fields as $field=>$fieldvalue) {
    if(file_exists(MODEL_PATH.$field.DIRECTORY_SEPARATOR.$classtype.'.inc.php')) {
      $cache_data .= file_get_contents(MODEL_PATH.$field.DIRECTORY_SEPARATOR.$classtype.'.inc.php');
    }
  }
  $cache_data .= "\r\n } \r\n?>";
  file_put_contents(CACHE_MODEL_PATH.'content_'.$classtype.'.class.php',$cache_data);
  chmod(CACHE_MODEL_PATH.'content_'.$classtype.'.class.php',0777);
}

这里通过遍历fields.inc.php文件中字段来遍历获取每个字段文件夹下面的orm.inc.php,input.inc.php,update.inc.php,output.inc.php的内容,然后将这些文件中的函数写到content_{classtype}.class.php文件中,这里就解释了刚刚调用的那些cache_model/下面的那些文件的由来。主要就是将每个自定义文件夹下面的操作函数添加到{modules}/fields/content_{classtype}.class.php文件中,然后把文件的内容写到缓存中去,方便我们在后期的直接加载该文件进行调用。

content_form.class.php文件的使用情况:

当我们要为一个模型添加数据的时候,这个时候就需要利用很传统的表单了。那么这个为模型添加数据的表单在PC中不是固定的。而是根据字段的情况来显示的。那么这里就要用到这个文件里。当要添加数据时,会调用这个文件来显示相关的表单控件

$modelid = $category['modelid'];
//取模型ID,依模型ID来生成对应的表单
require CACHE_MODEL_PATH.'content_form.class.php';
$content_form = new content_form($modelid,$catid,$this->categorys);
$forminfos = $content_form->get();

这段代码来自content控制器中add时间中,也就是当我们在后台点击添加新闻或者其他是会处理的一段代码,这里根据模型ID以及栏目ID来显示表单控件,来看下content_form.class.php文件中的get方法的部分代码

if(!method_exists($this, $func)) continue;
  $form = $this->$func($field, $value, $v);//调用相关字段(相当于表单的控件)的处理函数

这里的$func变量就是我们在添加字段的时候要选择的字段类型,这些字段类型肯定就是fields下面的某一个文件夹,这里通过调用该方法,来获取该该字段在添加内容的表单中如何显示。如果不存在也就是说在该字段文件夹下面没有form.inc.php这个文件。那么这个字段的值就不现实在添加内容的表单中。这里的这个方法我刚刚说过了 是在系统更新缓存的时候从每个自定义字段中获取然后写进去的。

这里就解释了我们在自定义字段的时候如果要想使用自己自定义的类型的话,那么就必须存在form.inc.ph文件。

content_input.class.php文件的使用情况:

原理和上面的文件是一样的。当我们使用自定义的类型时,如果没有input.inc.php文件,那么系统在获取数据的时候,判断在content_input.class.php文件中是否存在该方法,如果不存在,那么就不处理该字段的数据,直接按照获取的原型写入数据库中。所以要是我们想在我们自定义的字段类型中,想把获取的数据经过处理在写入DB那么就必须存在input.inc.php文件中的字段处理方法。

content_onput.class.php文件的使用情况:

他的情况恰好跟前者是相反的,这里不再多说了。

总之:用户要想添加一个字段,并且这个字段使用自己定义的类型的话,那么:

1、要想能够使用该字段,就必须把该字段的名称和信息添加到fields.inc.php文件中,使之生效,因为我们在后台添加字段的时候的那个选择字段类型就是从这个文件中读取的。如果你不添加的话,那么你就只能使用系统的那些格式。

2、要想自定义的类型能够出现在添加内容的表单中,那么form.inc.php这个文件中处理函数也是必不可少的。

3、要想自定义字段的数据在插入DB之前被处理下,那么input.inc.php文件中的处理函数也是必不可少的。

4、要想自定义的字段的数据在输出到页面是钱通过处理在显示的话,那么output.inc.php文件中处理函数也是必不可少的。

这样,自定义字段的大致功能就说完了,可能有不完整或不对的地方,请大家多多指教。。