protected function deliverJSON($api, $files) { // check for available updates for the given bundleidentifier // and return a JSON string with the result values $current = current($files[self::VERSIONS_SPECIFIC_DATA]); $apk = isset($current[self::FILE_ANDROID_APK]) ? $current[self::FILE_ANDROID_APK] : null; $json = isset($current[self::FILE_ANDROID_JSON]) ? $current[self::FILE_ANDROID_JSON] : null; $image = $files[self::VERSIONS_COMMON_DATA][self::FILE_COMMON_ICON]; if ($apk && $json) { $result = array(); $appversion = Router::arg(self::PARAM_2_APP_VERSION); // API version is V2 by default, even if the client provides V1 foreach ($files[self::VERSIONS_SPECIFIC_DATA] as $version) { $apk = $version[self::FILE_ANDROID_APK]; $json = $version[self::FILE_ANDROID_JSON]; $note = $version[self::FILE_COMMON_NOTES]; // parse the json file $parsed_json = json_decode(file_get_contents($json), true); $newAppVersion = array(); // add the latest release notes if available if ($note) { $newAppVersion[self::RETURN_V2_NOTES] = Helper::nl2br_skip_html(file_get_contents($note)); } $newAppVersion[self::RETURN_V2_TITLE] = $parsed_json['title']; $newAppVersion[self::RETURN_V2_SHORTVERSION] = $parsed_json['versionName']; $newAppVersion[self::RETURN_V2_VERSION] = $parsed_json['versionCode']; $newAppVersion[self::RETURN_V2_TIMESTAMP] = filectime($apk); $newAppVersion[self::RETURN_V2_APPSIZE] = filesize($apk); // add the latest release notes if available $note = $parsed_json['notes']; if ($note) { $newAppVersion[self::RETURN_V2_NOTES] = Helper::nl2br_skip_html($note); } $result[] = $newAppVersion; } return Helper::sendJSONAndExit($result); } Logger::log("no versions found: android/deliverJSON"); return Helper::sendJSONAndExit(self::E_NO_VERSIONS_FOUND); }
protected function getApplicationVersions($bundleidentifier, $platform = null) { $files = array(); $language = Router::arg(self::PARAM_2_LANGUAGE); // iOS $ipa = @array_shift(glob($this->appDirectory . $bundleidentifier . '/*' . self::FILE_IOS_IPA)); $plist = @array_shift(glob($this->appDirectory . $bundleidentifier . '/*' . self::FILE_IOS_PLIST)); $profile = @array_shift(glob($this->appDirectory . $bundleidentifier . '/*' . self::FILE_IOS_PROFILE)); // Android $apk = @array_shift(glob($this->appDirectory . $bundleidentifier . '/*' . self::FILE_ANDROID_APK)); $json = @array_shift(glob($this->appDirectory . $bundleidentifier . '/*' . self::FILE_ANDROID_JSON)); $note = ''; // Common if ($language) { $note = @array_shift(glob($this->appDirectory . $bundleidentifier . '/*' . self::FILE_COMMON_NOTES . '.' . $language)); } if (!$note) { $note = @array_shift(glob($this->appDirectory . $bundleidentifier . '/*' . self::FILE_COMMON_NOTES)); // the default language file should not have a language extension, so if en is default, never creaete a .html.en file! } $icon = @array_shift(glob($this->appDirectory . $bundleidentifier . '/*' . self::FILE_COMMON_ICON)); $allVersions = array(); if ((!$ipa || !$plist) && (!$apk || !$json)) { // check if any are available in a subdirectory $subDirs = array(); if ($handleSub = opendir($this->appDirectory . $bundleidentifier)) { while (($fileSub = readdir($handleSub)) !== false) { if (!in_array($fileSub, array('.', '..')) && is_dir($this->appDirectory . $bundleidentifier . '/' . $fileSub)) { array_push($subDirs, $fileSub); } } closedir($handleSub); } // Sort the files and display usort($subDirs, array($this, 'sort_versions')); if (count($subDirs) > 0) { foreach ($subDirs as $subDir) { // iOS $ipa = @array_shift(glob($this->appDirectory . $bundleidentifier . '/' . $subDir . '/*' . self::FILE_IOS_IPA)); // this file could be in a subdirectory per version $plist = @array_shift(glob($this->appDirectory . $bundleidentifier . '/' . $subDir . '/*' . self::FILE_IOS_PLIST)); // this file could be in a subdirectory per version // Android $apk = @array_shift(glob($this->appDirectory . $bundleidentifier . '/' . $subDir . '/*' . self::FILE_ANDROID_APK)); // this file could be in a subdirectory per version $json = @array_shift(glob($this->appDirectory . $bundleidentifier . '/' . $subDir . '/*' . self::FILE_ANDROID_JSON)); // this file could be in a subdirectory per version // Common $note = ''; // this file could be in a subdirectory per version if ($language) { $note = @array_shift(glob($this->appDirectory . $bundleidentifier . '/' . $subDir . '/*' . self::FILE_COMMON_NOTES . '.' . $language)); } if (!$note) { $note = @array_shift(glob($this->appDirectory . $bundleidentifier . '/' . $subDir . '/*' . self::FILE_COMMON_NOTES)); } $mandatory = @array_shift(glob($this->appDirectory . $bundleidentifier . '/' . $subDir . '/*' . self::FILE_VERSION_MANDATORY)); // this file defines if the version is mandatory $restrict = @array_shift(glob($this->appDirectory . $bundleidentifier . '/' . $subDir . '/*' . self::FILE_VERSION_RESTRICT)); // this file defines the teams allowed to access this version if ($ipa && $plist && (!$platform || $platform == self::PLATFORM_IOS)) { $version = array(); $version[self::FILE_IOS_IPA] = $ipa; $version[self::FILE_IOS_PLIST] = $plist; $version[self::FILE_COMMON_NOTES] = $note; $version[self::FILE_VERSION_RESTRICT] = $restrict; $version[self::FILE_VERSION_MANDATORY] = $mandatory; // if this is a restricted version, check if the UDID is provided and allowed if ($restrict && !$this->checkProtectedVersion($restrict)) { continue; } $allVersions[$subDir] = $version; } else { if ($apk && $json && (!$platform || $platform == self::PLATFORM_ANDROID)) { $version = array(); $version[self::FILE_ANDROID_APK] = $apk; $version[self::FILE_ANDROID_JSON] = $json; $version[self::FILE_COMMON_NOTES] = $note; $allVersions[$subDir] = $version; } } } if (count($allVersions) > 0) { $files[self::VERSIONS_SPECIFIC_DATA] = $allVersions; $files[self::VERSIONS_COMMON_DATA][self::FILE_IOS_PROFILE] = $profile; $files[self::VERSIONS_COMMON_DATA][self::FILE_COMMON_ICON] = $icon; } } } else { $version = array(); if ($ipa && $plist) { $version[self::FILE_IOS_IPA] = $ipa; $version[self::FILE_IOS_PLIST] = $plist; $version[self::FILE_COMMON_NOTES] = $note; $allVersions[] = $version; $files[self::VERSIONS_SPECIFIC_DATA] = $allVersions; $files[self::VERSIONS_COMMON_DATA][self::FILE_IOS_PROFILE] = $profile; $files[self::VERSIONS_COMMON_DATA][self::FILE_COMMON_ICON] = $icon; } else { if ($apk && $json) { $version[self::FILE_ANDROID_APK] = $apk; $version[self::FILE_ANDROID_JSON] = $json; $version[self::FILE_COMMON_NOTES] = $note; $allVersions[] = $version; $files[self::VERSIONS_SPECIFIC_DATA] = $allVersions; $files[self::VERSIONS_COMMON_DATA][self::FILE_COMMON_ICON] = $icon; } } } return $files; }
public function deliver($bundleidentifier, $api, $format) { $files = $this->getApplicationVersions($bundleidentifier, self::PLATFORM_IOS); if (count($files) == 0) { Logger::log("no versions found: {$bundleidentifier} {$api} {$type}"); return Helper::sendJSONAndExit(self::E_NO_VERSIONS_FOUND); } $current = current($files[self::VERSIONS_SPECIFIC_DATA]); $ipa = isset($current[self::FILE_IOS_IPA]) ? $current[self::FILE_IOS_IPA] : null; $plist = isset($current[self::FILE_IOS_PLIST]) ? $current[self::FILE_IOS_PLIST] : null; // notes file is optional, other files are required if (!$ipa || !$plist) { Logger::log("incomplete files: {$bundleidentifier} {$api} {$type}"); return Helper::sendJSONAndExit(self::E_FILES_INCOMPLETE); } $profile = $files[self::VERSIONS_COMMON_DATA][self::FILE_IOS_PROFILE]; $image = $files[self::VERSIONS_COMMON_DATA][self::FILE_COMMON_ICON]; $udid = Router::arg(self::PARAM_2_UDID); $appversion = Router::arg(self::PARAM_2_APP_VERSION) != null ? Router::arg(self::PARAM_2_APP_VERSION) : Router::arg(self::PARAM_1_APP_VERSION); $this->addStats($bundleidentifier, null); switch ($format) { case self::PARAM_2_FORMAT_VALUE_MOBILEPROVISION: Helper::sendFile($profile); break; case self::PARAM_2_FORMAT_VALUE_PLIST: $pos = strpos($current[self::FILE_IOS_IPA], $bundleidentifier); $ipa_file = substr($current[self::FILE_IOS_IPA], $pos); self::deliverIOSAppPlist($bundleidentifier, $plist, $image, $ipa_file); break; case self::PARAM_2_FORMAT_VALUE_IPA: Helper::sendFile($ipa); break; /* case self::TYPE_AUTH: if ($api != self::API_V1 && $udid && $appversion) { $this->deliverAuthenticationResponse($bundleidentifier, $udid, $appversion); } else { $this->deliverAuthenticationResponse(); } break; */ /* case self::TYPE_AUTH: if ($api != self::API_V1 && $udid && $appversion) { $this->deliverAuthenticationResponse($bundleidentifier, $udid, $appversion); } else { $this->deliverAuthenticationResponse(); } break; */ default: $this->deliverJSON($api, $files); break; } exit; }