<?php

class WPML_Term_Filters {

	public function init() {
		add_action( 'registered_taxonomy', array( $this, 'init' ), 10, 0 );
		$taxonomies = get_taxonomies();

		foreach ( $taxonomies as $taxonomy ) {
			if ( is_taxonomy_translated( $taxonomy ) ) {
				add_filter( "pre_option_{$taxonomy}_children", array( $this, 'pre_option_tax_children' ), 10, 0 );
				add_action( "create_{$taxonomy}", array( $this, 'update_tax_children_option' ), 10, 0 );
				add_action( "edit_{$taxonomy}", array( $this, 'update_tax_children_option' ), 10, 0 );
			}
		}
	}

	public function update_tax_children_option($taxonomy_input = false) {
		global $wpml_language_resolution, $wp_taxonomies;

		$language_codes    = $wpml_language_resolution->get_active_language_codes();
		$language_codes[ ] = 'all';
		$taxonomy          = str_replace( array( 'create_', 'edit_' ), '', current_action() );
		$taxonomy          = isset( $wp_taxonomies[ $taxonomy ] ) ? $taxonomy : $taxonomy_input;
		foreach ( $language_codes as $lang ) {
			$tax_children = $this->get_tax_hier_array( $taxonomy, $lang );
			$option_key   = "{$taxonomy}_children_{$lang}";
			update_option( $option_key, $tax_children );
		}
	}

	public function pre_option_tax_children() {
		global $sitepress;

		$taxonomy   = str_replace( array( 'pre_option_', '_children' ), '', current_filter() );
		$lang       = $sitepress->get_current_language();
		$option_key = "{$taxonomy}_children_{$lang}";

		$tax_children = get_option( $option_key, false );

		if ( $tax_children === false ) {
			$tax_children = $this->get_tax_hier_array( $taxonomy, $lang );
			update_option( $option_key, $tax_children );
		}

		return !empty($tax_children) ? $tax_children : false;
	}

	/**
	 * @param string $taxonomy
	 * @param string $lang_code
	 *
	 * @return array
	 */
	public function get_tax_hier_array( $taxonomy, $lang_code ) {
		global $wpdb;

		$hierarchy = array();

		if ( $lang_code != 'all' ) {
			$terms = $wpdb->get_results(
				$wpdb->prepare(
					"SELECT term_id, parent
					 FROM {$wpdb->term_taxonomy} tt
					 JOIN {$wpdb->prefix}icl_translations iclt
					  ON tt.term_taxonomy_id = iclt.element_id
					 WHERE tt.parent > 0
					  AND tt.taxonomy = %s
					  AND iclt.language_code = %s
					 ORDER BY term_id",
					$taxonomy,
					$lang_code
				)
			);
		} else {
			$terms = $wpdb->get_results(
				$wpdb->prepare(
					"SELECT term_id, parent
					 FROM {$wpdb->term_taxonomy} tt
					 WHERE tt.parent > 0
					  AND tt.taxonomy = %s
					 ORDER BY term_id",
					$taxonomy,
					$lang_code
				)
			);
		}

		foreach ( $terms as $term ) {
			if ( $term->parent > 0 ) {
				$hierarchy[ $term->parent ]    = isset( $hierarchy[ $term->parent ] )
					? $hierarchy[ $term->parent ] : array();
				$hierarchy[ $term->parent ][ ] = $term->term_id;
			}
		}

		return $hierarchy;
	}
}