HEX
Server: Apache
System: Linux sxb1plmcpnl510113.prod.sxb1.secureserver.net 4.18.0-553.58.1.lve.el8.x86_64 #1 SMP Fri Jul 4 12:07:06 UTC 2025 x86_64
User: acnbijigo78q (10488831)
PHP: 8.3.30
Disabled: NONE
Upload Files
File: /home/acnbijigo78q/public_html/jetk.sa/wp-content/plugins/wpml-elasticpress/src/Manager/Indices.php
<?php

namespace WPML\ElasticPress\Manager;

use ElasticPress\Elasticsearch;
use ElasticPress\Indexables;
use ElasticPress\Indexable;
use ElasticPress\Feature\Documents\Documents;
use WPML\ElasticPress\Traits\TranslateLanguages;

class Indices {

	use TranslateLanguages;

	const STOPWORD_FILTER_SLUG        = 'ep_stop';
	// Before ElasticPress 4.7.0
	const LEGACY_STOPWORD_FILTER_SLUG = 'stop';

	/** @var Elasticsearch */
	private $elasticsearch;

	/** @var Indexables */
	private $indexables;

	/** @var Documents */
	private $documentsFeature;

	/** @var Pipelines */
	private $pipelinesManager;

	/** @var array */
	private $activeLanguages;

	/** @var string */
	private $defaultLanguage;

	/** @var string */
	private $currentIndexLanguage = '';

	/** @var string|null */
	private $stopwordFilterSlug = null;

	/** @var string[]|null */
	private static $clusterIndices = null;

	/**
	 * @param Elasticsearch $elasticsearch
	 * @param Indexables    $indexables
	 * @param Documents     $documentsFeature
	 * @param Pipelines     $pipelinesManager
	 * @param array         $activeLanguages
	 * @param string        $defaultLanguage
	 */
	public function __construct(
		Elasticsearch $elasticsearch,
		Indexables    $indexables,
		Documents     $documentsFeature,
		Pipelines     $pipelinesManager,
		$activeLanguages,
		$defaultLanguage
	) {
		$this->elasticsearch    = $elasticsearch;
		$this->indexables       = $indexables;
		$this->documentsFeature = $documentsFeature;
		$this->pipelinesManager = $pipelinesManager;
		$this->activeLanguages  = $activeLanguages;
		$this->defaultLanguage  = $defaultLanguage;
	}

	public function addHooks() {
		add_filter( 'ep_index_name', [ $this, 'filterIndexName' ], 10 );
		add_filter( 'ep_global_alias', [ $this, 'filterIndexName' ], 10 );

		add_action( 'wp_initialize_site', [ $this, 'createBlogIndices' ], \WPML\ElasticPress\Constants::LATE_HOOK_PRIORITY );
		add_action( 'delete_blog', array( $this, 'deleteBlogIndices' ), \WPML\ElasticPress\Constants::LATE_HOOK_PRIORITY );
		add_action( 'make_delete_blog', array( $this, 'deleteBlogIndices' ), \WPML\ElasticPress\Constants::LATE_HOOK_PRIORITY );
		add_action( 'make_spam_blog', array( $this, 'deleteBlogIndices' ), \WPML\ElasticPress\Constants::LATE_HOOK_PRIORITY );
		add_action( 'archive_blog', array( $this, 'deleteBlogIndices' ), \WPML\ElasticPress\Constants::LATE_HOOK_PRIORITY );
		add_action( 'deactivate_blog', array( $this, 'deleteBlogIndices' ), \WPML\ElasticPress\Constants::LATE_HOOK_PRIORITY );
	}

	/**
	 * @param string  $indexName
	 *
	 * @return string
	 */
	public function filterIndexName( $indexName ) {
		if ( $this->currentIndexLanguage === $this->defaultLanguage ) {
			return $indexName;
		}
		if ( empty( $this->currentIndexLanguage ) ) {
			return $indexName;
		}
		return $indexName . '-' . $this->currentIndexLanguage;
	}

	/**
	 * @param string $language
	 */
	public function setCurrentIndexLanguage( $language ) {
		$this->currentIndexLanguage = $language;
	}

	public function clearCurrentIndexLanguage() {
		$this->currentIndexLanguage = '';
	}

	/**
	 * @return string[]
	 */
	private function getClusterIndicesCache() {
		if ( null === self::$clusterIndices ) {
			$clusterIndices = $this->elasticsearch->get_cluster_indices();
			self::$clusterIndices = wp_list_pluck( $clusterIndices, 'index' );
		}

		return self::$clusterIndices;
	}

	/**
	 * @param string $indexName
	 */
	private function saveIndexInClusterCache( $indexName ) {
		if ( null === self::$clusterIndices ) {
			self::$clusterIndices = [];
		}

		if ( in_array( $indexName, self::$clusterIndices, true ) ) {
			return;
		}

		self::$clusterIndices[] = $indexName;
	}

	private function clearClusterIndicesCache() {
		self::$clusterIndices = null;
	}

	/**
	 * @param  string $indexName
	 *
	 * @return bool
	 */
	public function indexExists( $indexName ) {
		$clusterIndices = $this->getClusterIndicesCache();

		return in_array( $indexName, $clusterIndices, true );
	}

	/**
	 * @param  array $filtersList
	 *
	 * @return string|null
	 */
	private function getStopwordFilterKey( $filtersList ) {
		if ( null !== $this->stopwordFilterSlug ) {
			return $this->stopwordFilterSlug;
		}
		if ( in_array( self::LEGACY_STOPWORD_FILTER_SLUG, $filtersList, true ) ) {
			$this->stopwordFilterSlug = self::LEGACY_STOPWORD_FILTER_SLUG;
		}
		if ( in_array( self::STOPWORD_FILTER_SLUG, $filtersList, true ) ) {
			$this->stopwordFilterSlug = self::STOPWORD_FILTER_SLUG;
		}
		return $this->stopwordFilterSlug;
	}

	/**
	 * @param Indexable $indexable
	 */
	public function generateIndexByIndexable( $indexable ) {
		$indexName = $indexable->get_index_name();
		// if document pipeline does not exist create it
		if ( $this->documentsFeature->is_active() && ! $this->pipelinesManager->documentPipelineExists( $indexName ) ) {
			$this->pipelinesManager->createDocumentPipeline();
		}
		if ( $this->indexExists( $indexName ) ) {
			return;
		}
		$mapping = $indexable->generate_mapping();

		// add attachments mapping if documents feature is active
		if ( $this->documentsFeature->is_active() ) {
			$mapping = $this->documentsFeature->attachments_mapping( $mapping );
		}
		if ( $this->defaultLanguage === $this->currentIndexLanguage ) {
			$this->elasticsearch->put_mapping( $indexName, $mapping );
			return;
		}
		$currentIndexLanguage = $this->currentIndexLanguage;
		$languages            = $this->generateAnalysisLanguages( $this->currentIndexLanguage );

		// Set analyzer and snowball languages
		$mapping['settings']['analysis']['analyzer']['default']['language'] = $languages['analyzer'];
		$mapping['settings']['analysis']['filter']['ewp_snowball']['language'] = $languages['snowball'];

		// Define language stopwords
		$stopwordFilterKey = $this->getStopwordFilterKey( $mapping['settings']['analysis']['analyzer']['default']['filter'] );
		if ( null !== $stopwordFilterKey ) {
			$mapping['settings']['analysis']['filter'][ $stopwordFilterKey ] = [
				'type'        => 'stop',
				'ignore_case' => true,
				'stopwords'   => '_' . $languages['analyzer'] . '_',
			];
		}

		// Define language stemmer
		if ( $this->languageHasStemmer( strtolower( $languages['analyzer'] ) ) ) {
			$mapping['settings']['analysis']['analyzer']['default']['filter'][] = 'stemmer_' . $this->currentIndexLanguage;
			$mapping['settings']['analysis']['filter']['stemmer_' . $this->currentIndexLanguage] = [
				'type'        => 'stemmer',
				'language'    => $languages['analyzer'],
			];
		}

		$this->elasticsearch->put_mapping( $indexName, $mapping );
		$this->saveIndexInClusterCache( $indexName );
	}

	/**
	 * @param Indexable[] $indexables
	 */
	public function generateIndexableIndexes( $indexables ) {
		foreach ( $indexables as $indexable ) {
			$this->generateIndexByIndexable( $indexable );
		}
	}

	public function clearAllIndices() {
		$this->elasticsearch->delete_all_indices();
		$this->clearClusterIndicesCache();
	}

	public function generateMissingIndices() {
		$indexables = $this->indexables->get_all();
		foreach ( $this->activeLanguages as $language ) {
			$this->setCurrentIndexLanguage( $language );
			$this->generateIndexableIndexes( $indexables );
			$this->clearCurrentIndexLanguage();
		}
	}

	/**
	 * @param \WP_Site $blog
	 */
	public function createBlogIndices( $blog ) {
		$indexable = $this->indexables->get( \WPML\ElasticPress\Constants::INDEXABLE_SLUG_POST );
		if ( false === $indexable ) {
			return;
		}

		foreach ( $this->activeLanguages as $language ) {
			$this->setCurrentIndexLanguage( $language );
			$indexable->sync_manager->action_create_blog_index( $blog );
			$this->clearCurrentIndexLanguage();
		}
	}

	/**
	 * @param int $blogId
	 */
	public function deleteBlogIndices( $blogId ) {
		$indexables = $this->indexables->get_all();
		foreach ( $indexables as $indexable ) {
			$this->deleteBlogLanguageIndices( $blogId, $indexable );
		}
	}

	/**
	 * @param int                     $blogId
	 * @param \ElasticPress\Indexable $indexable
	 */
	private function deleteBlogLanguageIndices( $blogId, $indexable ) {
		foreach ( $this->activeLanguages as $language ) {
			$this->setCurrentIndexLanguage( $language );
			$indexable->sync_manager->action_delete_blog_from_index( $blogId );
			$this->clearCurrentIndexLanguage();
		}
	}

}