= 1024px). * * @var int */ public $icon_attachment_id = 0; /** * Status/nav-bar tint, "#rrggbb". * * @var string */ public $theme_color = '#111111'; /** * Splash-screen background, "#rrggbb". * * @var string */ public $background_color = '#ffffff'; /** * GitHub owner/org the app repo lives under. * * @var string */ public $owner = ''; /** * App repo name (dedicated to this app, not the theme-sync repo). * * @var string */ public $repo = ''; /** * Branch the build workflow runs on. * * @var string */ public $branch = 'main'; /** * SHA-256 fingerprint of the signing certificate, for display. * * @var string */ public $keystore_fingerprint = ''; /** * MySQL datetime of the last time Esipher pushed the project + * dispatched a build, or '' if never. * * @var string */ public $last_build_dispatched_at = ''; /** * One of 'new' (nothing built yet), 'building' (files pushed, waiting * on GitHub) or 'error'. * * @var string */ public $status = 'new'; /** * Human-readable detail for the last failure, shown in the admin. * * @var string */ public $last_error = ''; /** * Apple Developer Team ID (10 chars). Empty = iOS builds are off. * * @var string */ public $apple_team_id = ''; /** * App Store Connect API key ID (the ".p8" itself is stored * separately and encrypted by Mobile_App_Store). * * @var string */ public $asc_key_id = ''; /** * App Store Connect API issuer ID (a UUID). * * @var string */ public $asc_issuer_id = ''; /** * Name of the App Store provisioning profile Esipher provisioned, * needed by the workflow's manual signing. Empty until first build. * * @var string */ public $ios_profile_name = ''; /** * iOS build lifecycle: 'new', 'building', or '' when iOS is off. * * @var string */ public $ios_status = ''; /** * Human-readable detail for the last iOS-specific failure. * * @var string */ public $ios_last_error = ''; /** * MySQL datetime of the last iOS build dispatch, or ''. * * @var string */ public $ios_last_build_dispatched_at = ''; /** * @return array */ public function to_array() { return array( 'app_name' => $this->app_name, 'app_id' => $this->app_id, 'site_url' => $this->site_url, 'icon_attachment_id' => $this->icon_attachment_id, 'theme_color' => $this->theme_color, 'background_color' => $this->background_color, 'owner' => $this->owner, 'repo' => $this->repo, 'branch' => $this->branch, 'keystore_fingerprint' => $this->keystore_fingerprint, 'last_build_dispatched_at' => $this->last_build_dispatched_at, 'status' => $this->status, 'last_error' => $this->last_error, 'apple_team_id' => $this->apple_team_id, 'asc_key_id' => $this->asc_key_id, 'asc_issuer_id' => $this->asc_issuer_id, 'ios_profile_name' => $this->ios_profile_name, 'ios_status' => $this->ios_status, 'ios_last_error' => $this->ios_last_error, 'ios_last_build_dispatched_at' => $this->ios_last_build_dispatched_at, ); } /** * @return bool Whether all three App Store Connect API fields are set * (the ".p8" presence is checked by Mobile_App_Store). */ public function ios_configured() { return '' !== trim( $this->apple_team_id ) && '' !== trim( $this->asc_key_id ) && '' !== trim( $this->asc_issuer_id ); } /** * @param array $data As produced by to_array(). * * @return self */ public static function from_array( array $data ) { $config = new self(); foreach ( $data as $key => $value ) { if ( property_exists( $config, $key ) ) { $config->$key = $value; } } return $config; } /** * @return string "owner/repo". */ public function full_name() { return $this->owner . '/' . $this->repo; } /** * A filesystem/npm-safe slug derived from the app name, for * package.json's "name" field. * * @return string */ public function package_slug() { $slug = sanitize_title( $this->app_name ); return '' !== $slug ? $slug : 'esipher-app'; } }