ok() ) { return null; } $list = self::clean( $result->body ); set_transient( self::TRANSIENT, $list, self::TTL ); return $list; } /** * The cached list, without asking LaunchList. * * @return array{forms: array, projects: array}|null */ public static function cached() { $cached = get_transient( self::TRANSIENT ); return is_array( $cached ) && isset( $cached['forms'], $cached['projects'] ) ? $cached : null; } /** * Drop the cache. * * @return void */ public static function forget() { delete_transient( self::TRANSIENT ); } /** * One form from a list. * * @param array|null $list The list. * @param string $id Form ID. * @return array|null */ public static function find( $list, $id ) { if ( ! is_array( $list ) || empty( $list['forms'] ) ) { return null; } foreach ( $list['forms'] as $form ) { if ( $form['id'] === $id ) { return $form; } } return null; } /** * The field LaunchList identifies a signup by: the one flagged `identity`, else the one keyed * `email`, else `email` of type `email`. * * @param array|null $form A form from the list. * @return array{key: string, type: string} */ public static function identity( $form ) { $fields = is_array( $form ) && isset( $form['fields'] ) ? $form['fields'] : array(); foreach ( $fields as $field ) { if ( ! empty( $field['identity'] ) ) { return array( 'key' => $field['key'], 'type' => $field['type'], ); } } foreach ( $fields as $field ) { if ( 'email' === strtolower( $field['key'] ) ) { return array( 'key' => $field['key'], 'type' => $field['type'], ); } } return array( 'key' => 'email', 'type' => 'email', ); } /** * Keep only the parts of the answer this plugin uses, each checked. * * @param array $body The answer. * @return array{forms: array, projects: array} */ public static function clean( array $body ) { $list = array( 'forms' => array(), 'projects' => array(), ); $forms = isset( $body['forms'] ) && is_array( $body['forms'] ) ? $body['forms'] : array(); foreach ( $forms as $form ) { if ( ! is_array( $form ) || ! isset( $form['id'] ) || ! is_string( $form['id'] ) || ! preg_match( self::FORM_ID, $form['id'] ) ) { continue; } $project = isset( $form['project'] ) && is_array( $form['project'] ) ? $form['project'] : array(); $fields = array(); foreach ( ( isset( $form['fields'] ) && is_array( $form['fields'] ) ? $form['fields'] : array() ) as $field ) { if ( ! is_array( $field ) || ! isset( $field['key'] ) || ! is_string( $field['key'] ) || '' === trim( $field['key'] ) ) { continue; } $key = Connection::truncate( trim( $field['key'] ), 100 ); $fields[] = array( 'key' => $key, 'label' => self::text( isset( $field['label'] ) ? $field['label'] : '', $key ), 'type' => self::slug( isset( $field['type'] ) ? $field['type'] : '' ), 'required' => ! empty( $field['required'] ), 'identity' => ! empty( $field['identity'] ), ); } $list['forms'][] = array( 'id' => $form['id'], 'name' => self::text( isset( $form['name'] ) ? $form['name'] : '', $form['id'] ), 'project' => array( 'name' => self::text( isset( $project['name'] ) ? $project['name'] : '', '' ), 'slug' => self::project_slug( isset( $project['slug'] ) ? $project['slug'] : '' ), ), 'fields' => $fields, ); } $projects = isset( $body['projects'] ) && is_array( $body['projects'] ) ? $body['projects'] : array(); foreach ( $projects as $project ) { if ( ! is_array( $project ) ) { continue; } $slug = self::project_slug( isset( $project['slug'] ) ? $project['slug'] : '' ); if ( '' === $slug ) { continue; } $widgets = array(); foreach ( ( isset( $project['widgets'] ) && is_array( $project['widgets'] ) ? $project['widgets'] : array() ) as $widget ) { if ( ! is_array( $widget ) || ! isset( $widget['id'] ) || ! is_string( $widget['id'] ) || ! Embed::valid_widget( $widget['id'] ) ) { continue; } $widgets[] = array( 'id' => $widget['id'], 'kind' => self::slug( isset( $widget['kind'] ) ? $widget['kind'] : '' ), 'name' => self::text( isset( $widget['name'] ) ? $widget['name'] : '', $widget['id'] ), ); } $list['projects'][] = array( 'name' => self::text( isset( $project['name'] ) ? $project['name'] : '', $slug ), 'slug' => $slug, 'widgets' => $widgets, ); } return $list; } /** * A plain display string, or a fallback when empty. * * @param mixed $value The value. * @param string $fallback Used when the value is empty. * @return string */ private static function text( $value, $fallback ) { $value = is_string( $value ) ? trim( sanitize_text_field( $value ) ) : ''; return '' === $value ? $fallback : Connection::truncate( $value, 200 ); } /** * A lowercase type or kind. * * @param mixed $value The value. * @return string */ private static function slug( $value ) { return is_string( $value ) ? substr( (string) preg_replace( '/[^a-z0-9_\-]/', '', strtolower( $value ) ), 0, 32 ) : ''; } /** * A project slug, or `""` when it is not one. * * @param mixed $value The value. * @return string */ private static function project_slug( $value ) { return is_string( $value ) && Embed::valid_slug( $value ) ? $value : ''; } }