Service - app间的扩展机制

什么是services

  • 让我们先来看一张图:
  • 接下来让我们借上图来解释一下services
  1. services是app之间扩展的重要方式。
  2. 我们将servicesservice看作是插槽插头的关系。一个插槽可以多个插头
  3. 每个app下都会有一个services.xml的文件,来描述本app的services,以及与本app相关的app的services
  4. 可以用kernel::service('service_name')获取一个最优先的服务者,或者用kernel::servicelist('service_name')获取所有服务提供者的列表。
    • 我们现在用services的思路改造我们的系统。

用service改造Gravatar

  • 修改控制器文件:app/notebook/controller/default.php 修改控制器上入口的调用方法,变成遍历service提供者,让每个提供者的输出都输出到页面里。
  • 我们这次用个更通用的方法,将get_avatar($item['email'])改成get_output($item)

    稍后我们会建立一个名字叫notebook_addon的服务,现在我们将入口改成查找服务notebook_addon

<?php
class notebook_ctl_default extends base_controller{

    public function 
index(){
        
$this->pagedata['items'] = $this->app->model('item')->getList('*');

        
//新修改的部分开始
        
foreach(kernel::servicelist('notebook_addon') as $object){
            foreach(
$this->pagedata['items'] as $k=>$item){
                
$this->pagedata['items'][$k]['addon'][] = $object->get_output($item);
            }
        }
        
//修改的部分结束

        
$this->display('default.html');
    }

    ...
}
  • 修改:app/notebook/lib/gravatar.php, 将get_avatar方法改成更通用的get_output方法。
<?php
class notebook_gravatar{

    function 
get_output($item){
        return 
sprintf('<img style="float:left;margin-right:10px"
            src="https://www.gravatar.com/avatar/%s?s=48&r=x" />'
,md5($item['item_email'])
        );
    }

}
  • 修改视图文件:app/notebook/view/default.html
    <{foreach from=$items item=item}>
    <dt>
    <{$item.item_subject}>
    <span class="date">日期: <{$item.item_posttime|cdate}></span>
    </dt>
    <dd>
    <!-- 变化的区域开始 -->
    <{foreach from=$item.addon item=block}>
        <{$block}>
    <{/foreach}>
    <!-- 变化的区域结束 -->
    <{$item.item_content}>
    </dd>
    <{/foreach}>
  • 新建notebook的服务定义文件:app/notebook/services.xml
  • 定义一个名字notebook_addon的服务。理论上,你可以定义任何名称。 我们推荐你使用自己app的名称作为service name的前缀
  • 将我们刚才定义好的类notebook_gravatar标示成该服务的一个实现。
<services>
	<service id="notebook_addon">
		<class>notebook_gravatar</class>
	</service>
</services>
  • 更新app的状态吧!修改了服务和数据库后都要重新更新app信息
    app/base/cmd update
    Updating base_application_service@notebook.
    Installing service notebook_addon
    Applications database and services is up-to-date, ok.
    
  • 可以看到后面那行Installing service notebook_addon现在访问前台,添加条留言看看


创建App, 添加一个小按钮

  • 我们现在创建一个新的app, 来扩展刚才的notebook
  • 创建新文件夹:app/alertnote
  • 编辑文件:app/alertnote/app.xml
    <app>
        <name>日记本扩展</name>
        <description>点一下就弹框...</description>
        <author>
            <name>somebody</name>
            <email>somebody@example.com</email>
            <url>https://www.example.com</url>
        </author>
        <depends>
            <app>notebook</app>
        </depends>
    </app>
    
  • 编辑服务配置文件:app/alertnote/services.xml 我们要向刚才的服务notebook_addon,注册一个新的实例
    <services>
    	<service id="notebook_addon">
    		<class>alertnote_tools</class>
    	</service>
    </services>
    
  • 编写具体的实现:app/alertnote/lib/tools.php
    <?php
    class alertnote_tools{

        function 
    get_output($item){
            return 
    '<span style="color:red" onclick="alert(\'警报! 警报! 警报!\')">警报</span>';
        }

    }
  • 安装本应用
    app/base/cmd install alertnote
    Installing service notebook_addon
    Application alertnote installed... ok.
    
  • 访问看看:


內容目录

上一个主题

类的自动载入机制

下一个主题

Desktop - 添加后台管理功能

快速搜索

输入相关的模块,术语,类或者函数名称进行搜索