在Ecos系统里, 每个APP会有很多的资源, 例如:service.xml, dbschema定义文件, site.xml等. 系统支持的资源会在APP进行安装 更新 卸载 暂停 启用时, 进行相应的安装,卸载等相应的资源.
Ecos对于资源的识别和管理, 是通过资源探测器来完成的.
系统里会内置多个核心的资源
其余的资源探测器, 都通过service的形式进行注册, 注册点为app_content_detctor
先来看看系统里目前已注册的资源探测器
./cmd dev:show services | grep -i app_content_detector
 
base_application_prototype_xml(xml文件资源探测器)类提供了可以遍历xml文件下某个节点下所有子节点的接口
base_application_prototype_filepath(目录资源探测器)类提供了可以遍历目录里所有文件或目录的接口
补充知识: 如果你希望支持其他类型的资源探测器,需要你自己进行扩展了. 开发需要预先学习[Iterator https://cn.php.net/manual/cn/class.iterator.php] 然后参考一下base_application_prototype_xml类和base_application_prototype_filepath类
因为最底层的基类implements Iterator, 所以对于Iterator, 还是要有个基本的了解
这里拿desktop app的后台权限探测器做个例子. 后台菜单探测器针对的是desktop.xml内寻取permissions下的所有pemission子节点.
首先要确认用哪种类型的探测器. 在本例中, 是针对xml类型的文件, 因此...
补充知识:
资源探测器存放的位置, 按照管理放在app/{$app_id}/lib/application目录下
<?php
class desktop_application_permission extends base_application_prototype_xml {
      ...
}
文件位置: app/desktop/lib/application/permission.php
首先需要在service中进行注册, 在desktop app中有一组针对desktop.xml的探测器.
app/desktop/desktop.xml
<services>
   ...
   <service id="app_content_detector">
        <class>desktop_application_permission</class>   
        <class>desktop_application_menu</class>
        <class>desktop_application_workground</class>
        <class>desktop_application_panelgroup</class>
        <class>desktop_application_adminpanel</class>
        <class>desktop_application_theme</class>
        <class>desktop_application_widgets</class>
    </service>
    ...
</services>
<?php
class desktop_application_permission extends base_application_prototype_xml {
    var $xml='desktop.xml'; //指定关注的xml资源, 本例中会调取app/desktop/desktop.xml, 本属性支持路径, 例如: 'abc/kkk.xml'
    var $xsd='desktop_content'; //指定xml对应的xsd位置, 本例中为 app/desktop/xmlschema/content.xsd
    var $path = 'permissions/permission'; //设定关注的xml的节点, 采用xpath的方式获取. 本例中意味着会在desktop.xml寻取permissions下的所有pemission子节点.
    ...
}
设置当前遍历子节点的内容($current)和当前元素的键($key)
通过$this->iterator()->current(), 可以获得当前xml子节点的array数据.
在本例中$this->iterator()->current()返回的是遍历到的当前permissions/permission/节点数据.
<?php
class desktop_application_permission extends base_application_prototype_xml {
    ...
    function current(){
        $this->current = $this->iterator()->current();
        $this->key = $this->current['id'];
        return $this;
    }
    ...
资源安装, 在app install时会调用
需要重载
安装当前遍历节点的数据
<?php
class desktop_application_permission extends base_application_prototype_xml {
    ...
    function install(){    
        kernel::log('Installing '.$this->content_typename().' '.$this->key());
        return app::get('desktop')->model('menus')->insert($this->row());
    }
    function row(){
        $row = array(
            'menu_type' => $this->content_typename(),
            'app_id'=>$this->target_app->app_id,
                );
        $row['menu_title'] = $this->current['value'];
        $row['display'] =  $this->current['display'];
        $access_opct = array(
            'show' => $this->current['show'],
            'save' => $this->current['save'],
                );
        $row['addon'] = serialize($access_opct);
        $row['permission'] = $this->current['id']; 
        return $row;
    }
    ...
    
资源卸载, 在app uninstall时会调用
<?php
class desktop_application_permission extends base_application_prototype_xml {
    function clear_by_app($app_id){
        if(!$app_id){
            return false;
        }
        app::get('desktop')->model('menus')->delete(array(
            'app_id'=>$app_id,'menu_type' => $this->content_typename()));
    }
资源更新, 在app update时会调用
update所有节点, 在基类中的实现会遍历所有节点, 然后对每个节点进行install通常不需要重载
资源卸载, 在app active时会调用
通常不需要重载
资源暂停, 在app pause时会调用
如果不重载此函数, 默认的情况是调用clear_by_app
通常不需要重载
和开发xml文件资源探测器的方式基本一致,区别在于:
可以参考: site_application_widgets类