> */ private static $languages; /** * Polylang's options. * * @var Options */ private $options; /** * Constructor. * * @since 3.4 * @since 3.7 The `$options` parameter is an instance of `Options`. * * @param Options $options Poylang's options. * @return void */ public function __construct( Options $options ) { $this->options = $options; } /** * Returns a language object matching the given data, looking up in cached transient. * * @since 3.4 * * @param array $language_data Language object properties stored as an array. See `PLL_Language::__construct()` * for information on accepted properties. * * @return PLL_Language A language object if given data pass sanitization. * * @phpstan-param LanguageData $language_data */ public function get( $language_data ) { return new PLL_Language( $this->sanitize_data( $language_data ) ); } /** * Returns a language object based on terms. * * @since 3.4 * * @param WP_Term[] $terms List of language terms, with the language taxonomy names as array keys. * `language` is a mandatory key for the object to be created, * `term_language` should be too in a fully operational environment. * @return PLL_Language|null Language object on success, `null` on failure. * * @phpstan-param array{language?:WP_Term}&array $terms */ public function get_from_terms( array $terms ) { if ( ! isset( $terms['language'] ) ) { return null; } $languages = $this->get_languages(); $data = array( 'name' => $terms['language']->name, 'slug' => $terms['language']->slug, 'term_group' => $terms['language']->term_group, 'term_props' => array(), 'is_default' => $this->options['default_lang'] === $terms['language']->slug, 'flag_code' => '', 'locale' => '', ); foreach ( $terms as $term ) { $data['term_props'][ $term->taxonomy ] = array( 'term_id' => $term->term_id, 'term_taxonomy_id' => $term->term_taxonomy_id, 'count' => $term->count, ); } // The description fields can contain any property. $description = maybe_unserialize( $terms['language']->description ); if ( is_array( $description ) ) { $description = array_intersect_key( $description, array( 'locale' => null, 'rtl' => null, 'flag_code' => null, 'active' => null, 'fallbacks' => null ) ); foreach ( $description as $prop => $value ) { if ( 'rtl' === $prop ) { $data['is_rtl'] = $value; } else { $data[ $prop ] = $value; } } } if ( ! empty( $data['locale'] ) ) { if ( isset( $languages[ $data['locale'] ]['w3c'] ) ) { $data['w3c'] = $languages[ $data['locale'] ]['w3c']; } else { $data['w3c'] = str_replace( '_', '-', $data['locale'] ); } if ( isset( $languages[ $data['locale'] ]['facebook'] ) ) { $data['facebook'] = $languages[ $data['locale'] ]['facebook']; } } $flag_props = $this->get_flag( $data['flag_code'], $data['name'], $data['slug'], $data['locale'] ); $data = array_merge( $data, $flag_props ); $additional_data = array(); /** * Filters additional data to add to the language before it is created. * * `home_url`, `search_url`, `page_on_front` and `page_for_posts` are only allowed. * * @since 3.4 * * @param array $additional_data. * @param array $data Language data. * * @phpstan-param array $additional_data * @phpstan-param non-empty-array $data */ $additional_data = apply_filters( 'pll_additional_language_data', $additional_data, $data ); $allowed_additional_data = array( 'home_url' => '', 'search_url' => '', 'page_on_front' => 0, 'page_for_posts' => 0, ); $data = array_merge( $data, array_intersect_key( $additional_data, $allowed_additional_data ) ); return new PLL_Language( $this->sanitize_data( $data ) ); } /** * Sanitizes data, to be ready to be used in the constructor. * This doesn't verify that the language terms exist. * * @since 3.4 * * @param array $data Data to process. See `PLL_Language::__construct()` for information on accepted data. * @return array Sanitized Data. * * @phpstan-return LanguageData */ private function sanitize_data( array $data ) { foreach ( $data['term_props'] as $tax => $props ) { $data['term_props'][ $tax ] = array_map( 'absint', $props ); } $data['is_rtl'] = ! empty( $data['is_rtl'] ) ? 1 : 0; $positive_fields = array( 'term_group', 'page_on_front', 'page_for_posts' ); foreach ( $positive_fields as $field ) { $data[ $field ] = ! empty( $data[ $field ] ) ? absint( $data[ $field ] ) : 0; } $data['active'] = isset( $data['active'] ) ? (bool) $data['active'] : true; if ( array_key_exists( 'fallbacks', $data ) && ! is_array( $data['fallbacks'] ) ) { unset( $data['fallbacks'] ); } $data['admin_flag'] = array(); if ( ! empty( $data['flag'] ) ) { $data['admin_flag']['aria-hidden'] = str_replace( '