插件开发文档:插件开发

自定义付款/支付/收费

在插件或系统的二次开发中会用到付款功能时,可以运用此教程来完成支付下单功能

image.png


例如插件目录:App/Test 插件


一、设计数据库

CREATE TABLE `dr_test` (
  `id` int(11) NOT NULL,
  `title` varchar(255) NOT NULL COMMENT '产品名称',
  `price` varchar(255) NOT NULL COMMENT '产品价格',
  `inputtime` int(11) NOT NULL COMMENT '发布时间'
) ENGINE=InnoDB DEFAULT CHARSET=utf8;

ALTER TABLE `dr_test`
  ADD PRIMARY KEY (`id`);
ALTER TABLE `dr_test`
  MODIFY `id` int(11) NOT NULL AUTO_INCREMENT;


二、设计表单支付模型

App/Models/Buy.php

 'Pay', // 字段类型
            'fieldname' => 'price',
            'setting' => [
                'option' => [
                    'payfile' => 'buy.html', // 模板文件 config/pay/buy.html
                    'is_finecms' => 1, // 是否启用余额付款
                ],
            ]
        ];
    }

    // 付款类型名称
    public function paytype() {
        return  ' 测试 '; // 最好2个汉字表述
    }
    
    // 付款前的权限验证,返回null表示可进行付款,返回字符串是就输出字符串
    // $id 记录id; $paylog 支付表记录数组; $num 数量; $sku 自定义属性
    public function pay_before($id, $num, $sku, $siteid) {
     return '';
    }

    // 付款价格
    // $id 记录id; $num 数量; $sku 自定义属性; $siteid 站点id
    public function get_price($id, $num, $sku, $siteid) {

        // 计算付款价格
        $data = $this->_get_row($id, $siteid);

        return $data['price']; // 测试200
    }

    // 付款数据
    // $id 记录id; $num 数量; $sku 自定义属性; $siteid 站点id
    public function get_row($id, $num, $sku, $siteid) {

        // 查询数据记录,判断是否存在
        $data = $this->_get_row($id, $siteid);

        return [
            'price' => $this->get_price($id, $num, $sku, $siteid),
            'title' => '支付记录标题'.$data['title'],
            'sell_uid' => 0, // 商家uid
            'sell_username' => '', // 商家账号
        ];
    }

    // 付款成功
    // $id 记录id; $paylog 支付表记录数组; $num 数量; $sku 自定义属性
    public function success($id, $paylog, $num, $sku) {

        // 支付成功之后的回调处理动作
        $data = $this->_get_row($id, $paylog['site']);

    }

    // 根据id查询表数据
    // $id 记录id;  $siteid 站点id
    private function _get_row($id, $siteid) {

        if (isset($this->row[$id]) && $this->row[$id]) {
            return $this->row[$id];
        }

        $this->row[$id] = $this->table('test')->get($id);

        return $this->row[$id];
    }
    
    
    // 付款成功跳转URL
    // $id 记录id; $paylog 支付表记录数组
    public function call_url($id, $paylog) {
        return dr_url_prefix("/index.php"); // 跳转url
    }
}


三、发起支付

表单参数格式:

my-插件目录_模型名称-相关ID-数量-SKU参数值 (数量-SKU参数值可以忽略)

那么调用表单格式为(可以放到任意前台html页面之中):

{dr_payform("my-test_buy-111")}

111表示test表的id号,cms会查询111记录的price字段作为付款金额


四、支付回调

上面(二)中的App/Models/Buy.php模型类,回调方法:success

开发者可以在success方法内完成支付后的动作,比如更新数据库等操作




插件联动缓存脚本

后台执行更新缓存时的联动脚本

文件:App/AppName/Config/Cache.php


内容格式:



任意表自定义字段

仅内部使用笔记


链接写法:

'自定义字段' => ['url:'.\Phpcmf\Service::L('Router')->url('field/index', ['rname'=>'table-表名称', 'rid'=>0]), 'fa fa-code'],


读取字段:

$myfield = \Phpcmf\Service::M('field')->get_mytable_field('表名称', 0);


赋值写法:

// 合并table字段
$myfield = \Phpcmf\Service::M('field')->get_mytable_field('表名称', 0);
$myfield && $field = dr_array22array($field, $myfield);


后台权限开发

方法一、后台标准化菜单权限划分

控制器菜单链接必须出现在后台菜单中。

如果后台设计到权限问题菜单,需要将控制器的方法名(fucntion 方法名())进行规范化命名

public function xxx_index() {
    // 使用权限的控制器方法命名 后缀_index
}
public function xxx_add() {
    // 添加权限的控制器方法命名 后缀_add
}
public function xxx_edit() {
    // 修改权限的控制器方法命名 后缀_edit
}
public function xxx_del() {
    // 删除权限的控制器方法命名 后缀_del
}
public function xxx_show() {
    // 查看权限的控制器方法命名 后缀_show
}

以上的“xxx_”可以省略不写!


后台模板判断某控制器是否具有操作权限:

{if $ci->_is_admin_auth('del')}
当前控制器运行del操作
{/if}


方法二、后台其他控制器的权限划分

如果控制器没有出现在后台菜单中,属于其他自定义控制器的权限。

1、比如此链接的权限控制

admin.php?s=demo&c=aaa&m=upload

如果这个链接不出现在后台菜单中的话,那么就只能在程序里面做权限判断了

QQ截图20210628111910

2、在插件modles目录创建Auth.php模型文件

例如插件目录是Demo,dayrui/App/Demo/Models/Auth.php



Clink和Cbottom权限验证

通过Clink和Cbottom可以在模块内容界面中显示对应的操作链接,本教程用于权限验证,决定哪个模块是否显示这些链接

如果不进行权限验证,那么所以模块都会显示这些链接


1、在插件modles目录创建Auth.php模型文件

例如插件目录是Demo,dayrui/App/Demo/Models/Auth.php


2、显示的模块效果

image.png

3、不显示的模块效果

image.png



------------clink支持对某条记录进行判断,是否在某条记录上显示这个侧部按钮-------------

1、配置check参数

dayrui/App/Demo/Config/Clink.php

 '确认签协议', // 站点权限是插件的链接名称
        'icon' => 'fa fa-edit', // 图标
        'color' => 'yellow', // 颜色class red green blue
        'uri' => 'demo/home/add', // 对应的uri权限判断,后面章节会介绍权限写法
        'field' => '', // 统计数量的字段,填写模块内容的主表字段,只能填写int数字类型的字段
        'check' => 'is_xieyi',
        'url' => '_javascript:;" onclick="dr_ajax_confirm_url(\''.dr_url('demo/home/xieyi_add', ['id' => '{cid}']).'\', \'确认签协议吗?\')',
    ],
 ]


2、新建模型

例如插件目录是Demo,dayrui/App/Demo/Models/Auth.php


自定义类文件类库

基于App目录下的插件或模块如何创建自己的类库

1、新建文件:dayrui/App/Test/Libraries/My.php

2、新写方法体:

全局调用格式为:

\Phpcmf\Service::L('class名称', 'app目录名称')->方法函数名称();

那么,以上定义的类库全局调用方法为:

\Phpcmf\Service::L('my', 'test')->hello();

模板中,调用方法:

{php echo \Phpcmf\Service::L('my', 'test')->hello();}


输入金额的付款/支付/收费

在插件或系统的二次开发中会用到付款功能时,可以运用此教程来完成支付下单功能

image

本教程用于让用户自己输入金额并付款的功能


例如插件目录:App/Test 插件


一、设计表单支付模型

App/Models/Buy.php

 'Pay', // 字段类型
            'fieldname' => 'price',
            'setting' => [
                'option' => [
                    'payfile' => 'pay.html', // 模板文件config/pay/pay.html
                    'is_finecms' => 1, // 是否启用余额付款
                ],
            ]
        ];
    }

    // 付款类型名称
    public function paytype() {
        return  ' 测试 '; // 最好2个汉字表述
    }
    
    // 付款前的权限验证,返回null表示可进行付款,返回字符串是就输出字符串
    // $id 记录id; $paylog 支付表记录数组; $num 数量; $sku 自定义属性
    public function pay_before($id, $num, $sku, $siteid) {
     return '';
    }
    
    // 付款后的验证,一般验证金额是否符合规则,返回null表示可进行付款,返回字符串是就输出字符串
    // $id 记录id; $paylog 支付表记录数组; $num 数量; $sku 自定义属性
    public function pay_after($id, $num, $sku, $siteid) {
  /*
  $price = $this->get_price($id, $num, $sku, $siteid);
  if ($price < 10) {
   return '最小支付10元';
  }*/
      return '';
    }

    // 付款价格
    // $id 记录id; $num 数量; $sku 自定义属性; $siteid 站点id
    public function get_price($id, $num, $sku, $siteid) {

        // 计算付款价格
        $data = $this->_get_row($id, $siteid);

        return $data['price']; // 测试200
    }

    // 付款数据
    // $id 记录id; $num 数量; $sku 自定义属性; $siteid 站点id
    public function get_row($id, $num, $sku, $siteid) {

        // 查询数据记录,判断是否存在
        $data = $this->_get_row($id, $siteid);

        return [
            'price' => $this->get_price($id, $num, $sku, $siteid),
            'title' => '支付记录标题'.$data['title'],
            'sell_uid' => 0, // 商家uid
            'sell_username' => '', // 商家账号
        ];
    }

    // 付款成功
    // $id 记录id; $paylog 支付表记录数组; $num 数量; $sku 自定义属性
    public function success($id, $paylog, $num, $sku) {

        // 支付成功之后的回调处理动作
        $data = $this->_get_row($id, $paylog['site']);

    }

    // 设置支付主题信息
    // $id 记录id;  $siteid 站点id
    private function _get_row($id, $siteid) {

        if (isset($this->row[$id]) && $this->row[$id]) {
            return $this->row[$id];
        }
        
        // 此方法只能用于支付前的调用,支付成功后将不能调用post值
 $pay = \Phpcmf\Service::L('input')->post('pay'); // 这里接受pay.html模板的输入金额值
        $this->row[$id] = [
     'title' => '义务捐赠收款',
     'price' => $pay['money'],
 ];

        return $this->row[$id];
    }
    
    
    // 付款成功跳转URL
    // $id 记录id; $paylog 支付表记录数组
    public function call_url($id, $paylog) {
        return dr_url_prefix("/index.php"); // 跳转url
    }
}


二、发起支付

表单参数格式:

my-插件目录_模型名称-相关ID-数量-SKU参数值 (数量-SKU参数值可以忽略)

那么调用表单格式为(可以放到任意前台html页面之中):

{dr_payform("my-test_buy-111")}

111表示标注的id号,可以作为发起收款的记录ID号,比如是什么情况下发起收款的


三、支付回调

上面(二)中的App/Models/Buy.php模型类,回调方法:success

开发者可以在success方法内完成支付后的动作,比如更新数据库等操作



插件自定义字段类别

在插件中加入自定义类别的扩展,如下图所示:

Markdown编辑器

官方实例插件:https://www.xunruicms.com/shop/app/708.html


以Demo插件目录为例,实现步骤:

1、创建字段配置文件dayrui/App/Demo/Fields/Field.php

 'Demo::Textarea', // 插件目录名::文件名称
        'name' => '测试文本编辑器',
    ],
];


2、创建字段解析文件dayrui/App/Demo/Fields/Textarea.php 文件命名与上面保持一致

fieldtype = TRUE;
        $this->defaulttype = 'TEXT'; // 默认显示的类型
    }

    /**
     * 字段相关属性参数
     */
    public function option($option) {
        return [
            $this->field_type($option['fieldtype'], $option['fieldlength']),
            ''
        ];
    }


    /**
     * 字段显示
     */
    public function show($field, $value = null) {
        $html = '
        
        
        
        '.nl2br(htmlentities($value)).'                
        
        
        ';         return $this->input_format($field['fieldname'], $field['name'], $html);     }     /**      * 字段表单输入      */     public function input($field, $value = '') {         // 字段禁止修改时就返回显示字符串         if ($this->_not_edit($field, $value)) {             return $this->show($field, $value);         }         // 字段存储名称         $name = $field['fieldname'];         // 字段显示名称         $text = ($field['setting']['validate']['required'] ? ' * ' : '').dr_lang($field['name']);         // 表单附加参数         $attr = $field['setting']['validate']['formattr'];         // 字段提示信息         $tips = $field['setting']['validate']['tips'] ? ''.$field['setting']['validate']['tips'].'' : '';         // 表单高度设置         $height = $field['setting']['option']['height'] ? $field['setting']['option']['height'] : '100';         // 字段默认值         $value = strlen($value) ? $value : $this->get_default_value($field['setting']['option']['value']);         $str = ''.$value.'';         return $this->input_format($name, $text, $str.$tips);     } }


这里的逻辑结构可以由开发者自由开发,例子以textarea为例。


4、然后在任意地方创建字段,可以选择本字段类别