1. 程式人生 > >微擎模組機制分析2

微擎模組機制分析2

 

2017年10月18日 17:51:06  閱讀數:1626  

利用微擎開發些微信公眾號還是非常方便的;模組機制分析主要從其安裝、解除安裝、使用角度,

 

一、安裝

安裝介面,主要是module_get_all_unistalled獲取未安裝模組

 

  1.   if ($do == 'not_installed') {
  2.   if (empty($_W['isfounder'])) {
  3.   itoast( '非法訪問!', referer(), 'info');
  4.   }
  5.   $_W[ 'page']['title'] = '安裝模組 - 模組 - 擴充套件';
  6.    
  7.   $status = $_GPC[ 'status'] == 'recycle'? 'recycle' : 'uninstalled';
  8.   $letters = array('A','B','C','D','E','F','G','H','I','J','K','L','M','N','O','P','Q','R','S','T','U','V','W','X','Y','Z');
  9.   $title = $_GPC[ 'title'];
  10.   $letter = $_GPC[ 'letter'];
  11.   $pageindex = max($_GPC[ 'page'], 1);
  12.   $pagesize = 20;
  13.    
  14.   $uninstallModules = module_get_all_unistalled($status, false);
  15.   $total_uninstalled = $uninstallModules[ 'module_count'];
  16.   $uninstallModules = ( array)$uninstallModules['modules'];
  17.   if (!empty($uninstallModules)) {
  18.   foreach($uninstallModules as $name => &$module) {
  19.   if (!empty($letter) && strlen($letter) == 1) {
  20.   $first_char = get_first_pinyin($module[ 'title']);
  21.   if ($letter != $first_char) {
  22.   unset($uninstallModules[$name]);
  23.   continue;
  24.   }
  25.   }
  26.   if (!empty($title)) {
  27.   if (!strexists($module['title'], $title)) {
  28.   unset($uninstallModules[$name]);
  29.   continue;
  30.   }
  31.   }
  32.    
  33.   if (file_exists(IA_ROOT.'/addons/'.$module['name'].'/icon-custom.jpg')) {
  34.   $module[ 'logo'] = tomedia(IA_ROOT.'/addons/'.$module['name'].'/icon-custom.jpg');
  35.   } elseif (file_exists(IA_ROOT.'/addons/'.$module['name'].'/icon.jpg')) {
  36.   $module[ 'logo'] = tomedia(IA_ROOT.'/addons/'.$module['name'].'/icon.jpg');
  37.   } else {
  38.   $module[ 'logo'] = tomedia($module['thumb']);
  39.   }
  40.   if (!empty($module['main_module'])) {
  41.   $main_module_installed = module_fetch($module[ 'main_module']);
  42.   if ($main_module_installed) {
  43.   $module[ 'main_module_logo'] = $main_module_installed['logo'];
  44.   } else {
  45.   if ($module['from'] == 'cloud') {
  46.   $module[ 'main_module_logo'] = tomedia($uninstallModules[$module['main_module']]['thumb']);
  47.   } else {
  48.   if (file_exists(IA_ROOT.'/addons/'.$module['main_module'].'/icon-custom.jpg')) {
  49.   $module[ 'main_module_logo'] = tomedia(IA_ROOT.'/addons/'.$module['main_module'].'/icon-custom.jpg');
  50.   } elseif (file_exists(IA_ROOT.'/addons/'.$module['main_module'].'/icon.jpg')) {
  51.   $module[ 'main_module_logo'] = tomedia(IA_ROOT.'/addons/'.$module['main_module'].'/icon.jpg');
  52.   }
  53.   }
  54.   }
  55.   }
  56.   }
  57.   }
  58.   $total = count($uninstallModules);
  59.   $uninstallModules = array_slice($uninstallModules, ($pageindex - 1)*$pagesize, $pagesize);
  60.   $pager = pagination($total, $pageindex, $pagesize);
  61.   }

module_get_all_unistalled 函式原始碼,可以看到先判斷是否有快取(微擎的快取實現機制還是很清晰易懂的,資料庫、檔案、memcache、Redis),沒有再取,關鍵是cache_build_uninstalled_module;可以看到有云模組的請求,當然這部分你可以幹掉,我還是堅持用正版哈

 

 

  1.   function module_get_all_unistalled($status, $cache = true) {
  2.   global $_GPC;
  3.   load()->func( 'communication');
  4.   load()->model( 'cloud');
  5.   load()->classs( 'cloudapi');
  6.   $status = $status == 'recycle' ? 'recycle' : 'uninstalled';
  7.    
  8.    
  9.    
  10.   $uninstallModules = cache_load(cache_system_key( 'module:all_uninstall'));
  11.    
  12.   if (!$cache && $status == 'uninstalled') {
  13.   $cloud_api = new CloudApi();
  14.   $get_cloud_m_count = $cloud_api->get( 'site', 'stat', array('module_quantity' => 1), 'json');
  15.   $cloud_m_count = $get_cloud_m_count[ 'module_quantity'];
  16.   } else {
  17.    
  18.   if(is_array($uninstallModules)){
  19.   $cloud_m_count = $uninstallModules[ 'cloud_m_count'];
  20.   }
  21.   }
  22.   if (empty($uninstallModules['modules']) || intval($uninstallModules['cloud_m_count']) !== intval($cloud_m_count) || is_error($get_cloud_m_count)) {
  23.    
  24.   $uninstallModules = cache_build_uninstalled_module();
  25.   }
  26.   if (ACCOUNT_TYPE == ACCOUNT_TYPE_APP_NORMAL) {
  27.   $uninstallModules[ 'modules'] = (array)$uninstallModules['modules'][$status]['wxapp'];
  28.   $uninstallModules[ 'module_count'] = $uninstallModules['wxapp_count'];
  29.   return $uninstallModules;
  30.   } elseif (ACCOUNT_TYPE == ACCOUNT_TYPE_OFFCIAL_NORMAL) {
  31.   $uninstallModules[ 'modules'] = (array)$uninstallModules['modules'][$status]['app'];
  32.   $uninstallModules[ 'module_count'] = $uninstallModules['app_count'];
  33.   return $uninstallModules;
  34.   } else {
  35.   return $uninstallModules;
  36.   }
  37.   }

cache_build_uninstalled_module原始碼,現在知道為什麼模組要放在addons下了,最後還把模組資訊寫入快取,以便下次直接使用

 

 

  1.   function cache_build_uninstalled_module() {
  2.   load()->model( 'cloud');
  3.   load()->classs( 'cloudapi');
  4.   load()->model( 'extension');
  5.   load()->func( 'file');
  6.   $cloud_api = new CloudApi();
  7.    
  8.   $cloud_m_count = $cloud_api->get( 'site', 'stat', array('module_quantity' => 1), 'json');
  9.    
  10.    
  11.    
  12.   $installed_module = pdo_getall( 'modules', array(), array(), 'name');
  13.    
  14.   $uninstallModules = array('recycle' => array(), 'uninstalled' => array());
  15.   $recycle_modules = pdo_getall( 'modules_recycle', array(), array(), 'modulename');
  16.   $recycle_modules = array_keys($recycle_modules);
  17.   $cloud_module = cloud_m_query();
  18.    
  19.   if (!empty($cloud_module) && !is_error($cloud_module)) {
  20.   foreach ($cloud_module as $module) {
  21.   $upgrade_support_module = false;
  22.   $wxapp_support = ! empty($module['site_branch']['wxapp_support']) && is_array($module['site_branch']['bought']) && in_array('wxapp', $module['site_branch']['bought']) ? $module['site_branch']['wxapp_support'] : 1;
  23.   $app_support = ! empty($module['site_branch']['app_support']) && is_array($module['site_branch']['bought']) && in_array('app', $module['site_branch']['bought']) ? $module['site_branch']['app_support'] : 1;
  24.   if ($wxapp_support == 1 && $app_support == 1) {
  25.   $app_support = 2;
  26.   }
  27.   if (!empty($installed_module[$module['name']]) && ($installed_module[$module['name']]['app_support'] != $app_support || $installed_module[$module['name']]['wxapp_support'] != $wxapp_support)) {
  28.   $upgrade_support_module = true;
  29.   }
  30.   if (!in_array($module['name'], array_keys($installed_module)) || $upgrade_support_module) {
  31.   $status = in_array($module[ 'name'], $recycle_modules) ? 'recycle' : 'uninstalled';
  32.   if (!empty($module['id'])) {
  33.   $cloud_module_info = array (
  34.   'from' => 'cloud',
  35.   'name' => $module['name'],
  36.   'version' => $module['version'],
  37.   'title' => $module['title'],
  38.   'thumb' => $module['thumb'],
  39.   'wxapp_support' => $wxapp_support,
  40.   'app_support' => $app_support,
  41.   'main_module' => empty($module['main_module']) ? '' : $module['main_module'],
  42.   'upgrade_support' => $upgrade_support_module
  43.   );
  44.   if ($upgrade_support_module) {
  45.   if ($wxapp_support == 2 && $installed_module[$module['name']]['wxapp_support'] != 2) {
  46.   $uninstallModules[$status][ 'wxapp'][$module['name']] = $cloud_module_info;
  47.   }
  48.   if ($app_support == 2 && $installed_module[$module['name']]['app_support'] != 2) {
  49.   $uninstallModules[$status][ 'app'][$module['name']] = $cloud_module_info;
  50.   }
  51.   } else {
  52.   if ($wxapp_support == 2) {
  53.   $uninstallModules[$status][ 'wxapp'][$module['name']] = $cloud_module_info;
  54.   }
  55.   if ($app_support == 2) {
  56.   $uninstallModules[$status][ 'app'][$module['name']] = $cloud_module_info;
  57.   }
  58.   }
  59.   }
  60.   }
  61.   }
  62.   }
  63.   $path = IA_ROOT . '/addons/';
  64.   mkdirs($path);
  65.    
  66.   $module_file = glob($path . '*');
  67.   if (is_array($module_file) && !empty($module_file)) {
  68.   foreach ($module_file as $modulepath) {
  69.   $upgrade_support_module = false;
  70.   $modulepath = str_replace($path, '', $modulepath);
  71.   $manifest = ext_module_manifest($modulepath);
  72.   if (!is_array($manifest) || empty($manifest) || empty($manifest['application']['identifie'])) {
  73.   continue;
  74.   }
  75.   $main_module = empty($manifest['platform']['main_module']) ? '' : $manifest['platform']['main_module'];
  76.   $manifest = ext_module_convert($manifest);
  77.    
  78.   if (!empty($installed_module[$modulepath]) && ($manifest['app_support'] != $installed_module[$modulepath]['app_support'] || $manifest['wxapp_support'] != $installed_module[$modulepath]['wxapp_support'])) {
  79.   $upgrade_support_module = true;
  80.   }
  81.   if (!in_array($manifest['name'], array_keys($installed_module)) || $upgrade_support_module) {
  82.   $module[$manifest[ 'name']] = $manifest;
  83.   $module_info = array(
  84.   'from' => 'local',
  85.   'name' => $manifest['name'],
  86.   'version' => $manifest['version'],
  87.   'title' => $manifest['title'],
  88.   'app_support' => $manifest['app_support'],
  89.   'wxapp_support' => $manifest['wxapp_support'],
  90.   'main_module' => $main_module,
  91.   'upgrade_support' => $upgrade_support_module
  92.   );
  93.   $module_type = in_array($manifest[ 'name'], $recycle_modules) ? 'recycle' : 'uninstalled';
  94.   if ($upgrade_support_module) {
  95.   if ($module_info['app_support'] == 2 && $installed_module[$module_info['name']]['app_support'] != 2) {
  96.   $uninstallModules[ 'uninstalled']['app'][$manifest['name']] = $module_info;
  97.   }
  98.   if ($module_info['wxapp_support'] == 2 && $installed_module[$module_info['name']]['wxapp_support'] != 2) {
  99.   $uninstallModules[ 'uninstalled']['wxapp'][$manifest['name']] = $module_info;
  100.   }
  101.   } else {
  102.   if ($module_info['app_support'] == 2) {
  103.   $uninstallModules[$module_type][ 'app'][$manifest['name']] = $module_info;
  104.   }
  105.   if ($module_info['wxapp_support'] == 2) {
  106.   $uninstallModules[$module_type][ 'wxapp'][$manifest['name']] = $module_info;
  107.   }
  108.   }
  109.   }
  110.   }
  111.   }
  112.   $cache = array(
  113.   'cloud_m_count' => $cloud_m_count['module_quantity'],
  114.   'modules' => $uninstallModules,
  115.   'app_count' => count($uninstallModules['uninstalled']['app']),
  116.   'wxapp_count' => count($uninstallModules['uninstalled']['wxapp'])
  117.   );
  118.    
  119.    
  120.   cache_write( 'we7:module:all_uninstall', $cache, CACHE_EXPIRE_LONG);
  121.   return $cache;
  122.   }

還有個地方值得學習,模組的資訊定義在manifest.xml中,有點java的感覺,具體資訊讀取都在extension.mod.php中,程式碼如下

 

 

 

  1.   function ext_module_manifest_parse($xml) {
  2.   if (!strexists($xml, '<manifest')) {
  3.   $xml = base64_decode($xml);
  4.   }
  5.   if (empty($xml)) {
  6.   return array();
  7.   }
  8.   $dom = new DOMDocument();
  9.   $dom->loadXML($xml);
  10.   $root = $dom->getElementsByTagName( 'manifest')->item(0);
  11.   if (empty($root)) {
  12.   return array();
  13.   }
  14.   $vcode = explode( ',', $root->getAttribute('versionCode'));
  15.   $manifest[ 'versions'] = array();
  16.   if (is_array($vcode)) {
  17.   foreach ($vcode as $v) {
  18.   $v = trim($v);
  19.   if (!empty($v)) {
  20.   $manifest[ 'versions'][] = $v;
  21.   }
  22.   }
  23.   $manifest[ 'versions'][] = '0.52';
  24.   $manifest[ 'versions'][] = '