IpaParser.php 7.3 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179
  1. <?php
  2. /**
  3. * 解析Ipa plist文件
  4. *
  5. * @author zhoushen extrembravo@gmail.com
  6. * @since 2014/2/14
  7. */
  8. require dirname(__FILE__).'/CFPropertyList/CFPropertyList.php';
  9. class IpaParser {
  10. const INFO_PLIST = 'Info.plist';
  11. public function parse($ipaFile, $infoFile = self::INFO_PLIST) {
  12. $zipObj = new ZipArchive();
  13. if ($zipObj->open($ipaFile) !== true) {
  14. throw new PListException("unable to open {$ipaFile} file!");
  15. }
  16. // scan plist file
  17. $plistFile = null;
  18. for ($i = 0; $i < $zipObj->numFiles; $i++) {
  19. $name = $zipObj->getNameIndex($i);
  20. if (preg_match('/Payload\/(.+)?\.app\/'.preg_quote($infoFile).'$/i', $name)) {
  21. $plistFile = $name;
  22. break;
  23. }
  24. }
  25. // parse plist file
  26. if (!$plistFile) {
  27. throw new PListException("unable to parse plist file!");
  28. }
  29. // deal in memory
  30. $plistHandle = fopen('php://memory', 'wb');
  31. fwrite($plistHandle, $zipObj->getFromName($plistFile));
  32. rewind($plistHandle);
  33. $zipObj->close();
  34. $plist = new CFPropertyList($plistHandle, CFPropertyList::FORMAT_AUTO);
  35. $this->plistContent = $plist->toArray();
  36. return true;
  37. }
  38. // 获取包名
  39. public function getPackage() {
  40. return $this->plistContent['CFBundleIdentifier'];
  41. }
  42. // 获取版本
  43. public function getVersion() {
  44. return $this->plistContent['CFBundleVersion'];
  45. }
  46. // 获取应用名称
  47. public function getAppName() {
  48. return $this->plistContent['CFBundleDisplayName'];
  49. }
  50. // 获取解析后的plist文件
  51. public function getPlist() {
  52. return $this->plistContent;
  53. }
  54. /**
  55. * 生成下载plist文件
  56. *
  57. * @param string $path 文件指定存放路径
  58. * @param string $downurl ipa下载地址
  59. * @param array $data 数据数组
  60. * @param string $logo_url 图标路径
  61. */
  62. public function createPlist($path, $downurl, $data = [], $logo_url = '') {
  63. $plist = new CFPropertyList();
  64. /*
  65. * 手动创建sample.xml.plist
  66. */
  67. $packname = $data['pakagename'];
  68. $title = $data['appname'].'(安装完成之后,请到设置->通用->描述文件与设备管理,信任企业级应用)';
  69. $version = $data['vername'];
  70. $plist->add($dict = new CFDictionary());
  71. $dict->add('items', $items_array = new CFArray());
  72. $items_array->add($items_array_dict = new CFDictionary());
  73. $items_array_dict->add('assets', $assets_array = new CFArray());
  74. $assets_array->add($assets_dict1 = new CFDictionary());
  75. $assets_dict1->add('kind', new CFString('software-package'));
  76. $assets_dict1->add('url', new CFString($downurl));
  77. if (!empty($logo_url)) {
  78. $assets_array->add($assets_dict2 = new CFDictionary());
  79. $assets_dict2->add('kind', new CFString('full-size-image'));
  80. $assets_dict2->add('needs-shine', new CFBoolean(true));
  81. $assets_dict2->add('url', new CFString($logo_url));
  82. $assets_array->add($assets_dict3 = new CFDictionary());
  83. $assets_dict3->add('kind', new CFString('display-image'));
  84. $assets_dict3->add('needs-shine', new CFBoolean(true));
  85. $assets_dict3->add('url', new CFString($logo_url));
  86. }
  87. $items_array_dict->add('metadata', $metadata_dict = new CFDictionary());
  88. $metadata_dict->add('bundle-identifier', new CFString($packname));
  89. $metadata_dict->add('bundle-version', new CFString($version));
  90. $metadata_dict->add('kind', new CFString('software'));
  91. $metadata_dict->add('subtitle', new CFString($data['appname']));
  92. $metadata_dict->add('title', new CFString($title));
  93. $plist->saveXML($path);
  94. }
  95. /**
  96. * 创建Webclip
  97. *
  98. * @method : createMobileCnf
  99. * @param : $path weblip文件路径(绝对路径)
  100. * @param : $iconpath weblip中icon路径
  101. * @param : $url weblip跳转的web路径
  102. * @param : $data array 包名 应用名 版本
  103. *
  104. * @return :
  105. * @author : wuyonghong <wyh@huosdk.com>
  106. * @date : 2016年12月10日下午3:40:11
  107. * @since 7.0
  108. * @modified:
  109. */
  110. public function createWebclip($path, $iconpath, $url, array $data) {
  111. $packname = $data['pakagename'];
  112. $toolname = $data['appname'];
  113. $uuid = (string)$this->gen_uuid();
  114. $identifier = strtoupper(gethostname()).(string)$uuid;
  115. $plist = new CFPropertyList();
  116. $plist->add($dict = new CFDictionary());
  117. /* 添加mobileconfig基本信息 */
  118. $dict->add('PayloadContent', $dict_arr = new CFArray());
  119. $dict->add(
  120. 'PayloadDescription',
  121. new CFString("修复".$toolname."程序.当".$toolname."闪退时使用\"修复".$toolname."\"进行修复.")
  122. );
  123. $dict->add('PayloadDisplayName', new CFString("修复".$toolname));
  124. $dict->add('PayloadIdentifier', new CFString($packname.$identifier));
  125. $dict->add('PayloadOrganization', new CFString(''));
  126. $dict->add('PayloadRemovalDisallowed', new CFBoolean(false));
  127. $dict->add('PayloadType', new CFString('Configuration'));
  128. $dict->add('PayloadUUID', new CFString($uuid));
  129. $dict->add('PayloadVersion', new CFNumber(1));
  130. $icondata = base64_encode(file_get_contents($iconpath));
  131. $icon_arr = str_split($icondata, 52);
  132. $icondata = implode(' ', $icon_arr);
  133. /* 添加存储信息 */
  134. $dict_arr->add($arr_dict = new CFDictionary());
  135. $arr_dict->add('FullScreen', new CFBoolean(false));
  136. $arr_dict->add('Icon', new CFData($icondata, true));
  137. $arr_dict->add('IsRemovable', new CFBoolean(true));
  138. $arr_dict->add('Label', new CFString('修复'.$toolname));
  139. $arr_dict->add('PayloadDescription', new CFString('Adds a Web Clip.'));
  140. $arr_dict->add('PayloadDisplayName', new CFString('Web Clip (修复'.$toolname.')'));
  141. $arr_dict->add('PayloadIdentifier', new CFString($packname.$identifier.'webclip'));
  142. $arr_dict->add('PayloadOrganization', new CFString(''));
  143. $arr_dict->add('PayloadType', new CFString('com.apple.webClip.managed'));
  144. $arr_dict->add('PayloadUUID', new CFString($identifier));
  145. $arr_dict->add('PayloadVersion', new CFNumber(1));
  146. $arr_dict->add('Precomposed', new CFBoolean(false));
  147. $arr_dict->add('URL', new CFString($url));
  148. $plist->saveXML($path);
  149. }
  150. protected function gen_uuid() {
  151. if (function_exists('com_create_guid')) {
  152. return trim(com_create_guid(), '{}');
  153. } else {
  154. mt_srand((double)microtime() * 10000); // optional for php 4.2.0 and up.随便数播种,4.2.0以后不需要了。
  155. $charid = strtoupper(md5(uniqid(rand(), true))); // 根据当前时间(微秒计)生成唯一id.
  156. $hyphen = chr(45); // "-"
  157. $uuid = ''.substr($charid, 0, 8).$hyphen.substr($charid, 8, 4).$hyphen.substr($charid, 12, 4).$hyphen
  158. .substr(
  159. $charid,
  160. 16,
  161. 4
  162. ).$hyphen.substr($charid, 20, 12);
  163. return $uuid;
  164. }
  165. return rtrim(shell_exec("uuidgen"));
  166. }
  167. }