<commit_before><?php
/**
 * @package framework.service
 * TagService
 */
class TagService extends BaseService
{
	/**
	 * the singleton instance
	 * @var TagService
	 */
	private static $instance = null;

	private $tagsInfo;
	
	private $availableTags;

	const TAG_REGEXP = '/^[0-9a-z\-\._]+$/i';

	/**
	 * @return TagService
	 */
	public static function getInstance()
	{
		if (is_null(self::$instance))
		{
			self::$instance = self::getServiceClassInstance(get_class());
		}
		return self::$instance;
	}

	/**
	 * @param String $pattern
	 * @return Array<String => Array>
	 */
	public function getAllAvailableTags()
	{
		return $this->getAvailableTagsInfo();
	}

	/**
	 * Find tags by pattern containing * wildcards ( eg: contextual_website_website_menu* )
	 *
	 * @param String $pattern
	 * @return array
	 */
	public function getAvailableTagsByPattern($pattern)
	{
		$tags = array();
		$reg = '/^' . str_replace('*', '.*', $pattern) . '$/';
		foreach ($this->getAvailableTags() as $tag) 
		{
			if (preg_match($reg, $tag)) {$tags[] = $tag;}
		}
		return $tags;
	}

	/**
	 * @param f_persistentdocument_PersistentDocument $document
	 * @return array
	 */
	function getAffectedTagsForDocument($document)
	{
		$tags = array();
		$model = $document->getPersistentModel();
		$modelsName = array();
		while (true)
		{
			if ($model->isInjectedModel()) {$model = $model->getSourceInjectionModel();}
			$modelsName[$model->getName()] = true;
			if (!$model->hasParent()) {break;}
			$model = f_persistentdocument_PersistentDocumentModel::getInstanceFromDocumentModelName($model->getParentName());
		}
		
		$allTags = $this->getPersistentProvider()->getAllTags();
		$results = array();
		foreach ($this->getAvailableTagsInfo() as $tag => $tagInfo) 
		{
			if (isset($modelsName[$tagInfo['component_type']]))
			{
				$results[] = array('tag' => $tag, 'ids' => isset($allTags[$tag]) ? $allTags[$tag] : array());			
			}
		}
		
		$parent = $document->getDocumentService()->getParentOf($document);	
		$websiteId = $document->getDocumentService()->getWebsiteId($document);
		
		$documentId = $document->getId();
		foreach ($results as $result)
		{
			$tag = $result['tag'];
			if (in_array($documentId, $result['ids']))
			{
				$tags[] = array('tag' => $tag, 'affected' => true, 'selfAffected' => true);
			}
			else if (count($result['ids']) > 0)
			{
				if ($this->isExclusiveTag($tag))
				{
					// Exclusive tags does not need context check.
					$tags[] = array('tag' => $tag, 'affected' => true);
				}
				else if ($this->isContextualTag($tag))
				{
					// Check that the id is a descendent of the same website than the given document.
					if ($websiteId)
					{
						foreach ($result['ids'] as $taggedDocumentId) 
						{
							$taggedDocument = DocumentHelper::getDocumentInstance($taggedDocumentId);
							$taggedWebsiteId = $taggedDocument->getDocumentService()->getWebsiteId($taggedDocument);			
							if ($taggedWebsiteId == $websiteId)
							{
								$tags[] = array('tag' => $tag, 'affected' => true);
								break;
							}
						}
					}
				}
				else if ($this->isFunctionalTag($tag))
				{
					// Check that the id and the given document has the same parent.
					if (isset($parent))
					{
						foreach ($result['ids'] as $taggedDocumentId) 
						{
							$taggedDocument = DocumentHelper::getDocumentInstance($taggedDocumentId);
							$taggedDocumentParent = $taggedDocument->getDocumentService()->getParentOf($taggedDocument);
							if (DocumentHelper::equals($parent, $taggedDocumentParent))
							{
								$tags[] = array('tag' => $tag, 'affected' => true);
								break;
							}							
						}
					}
				}
				else
				{
					// FIXME: What to do for free tags?
				}
			}
		}

		return array('models' => $modelsName, 'tags' => $tags) ;
	}

	/**
	 * This method is used internally to check if a tag is valid or not.
	 * @param string $tag The tag to check.
	 * @return boolean true if $tag is a valid tag, false otherwise.
	 */
	public function isValidTag($tag)
	{
		return ( is_numeric($tag) || ( is_string($tag) && preg_match(self::TAG_REGEXP, $tag) ) );
	}


	/**
	 * This method is used internally to check if a tag is exclusive (can appear
	 * only once in all the tags).
	 * @param string $tag The tag to check.
	 * @return boolean true if $tag is an exclusive tag or false otherwise.
	 */
	public function isExclusiveTag($tag)
	{
		return $this->isValidTag($tag) && substr($tag, 0, 8) === 'default_';<commit_msg>[FIX #59748] Memory limit + LoadTags (3.5.5)<commit_after><?php
/**
 * @package framework.service
 * TagService
 */
class TagService extends BaseService
{
	/**
	 * the singleton instance
	 * @var TagService
	 */
	private static $instance = null;

	private $tagsInfo;
	
	private $availableTags;

	const TAG_REGEXP = '/^[0-9a-z\-\._]+$/i';

	/**
	 * @return TagService
	 */
	public static function getInstance()
	{
		if (is_null(self::$instance))
		{
			self::$instance = self::getServiceClassInstance(get_class());
		}
		return self::$instance;
	}

	/**
	 * @param String $pattern
	 * @return Array<String => Array>
	 */
	public function getAllAvailableTags()
	{
		return $this->getAvailableTagsInfo();
	}

	/**
	 * Find tags by pattern containing * wildcards ( eg: contextual_website_website_menu* )
	 *
	 * @param String $pattern
	 * @return array
	 */
	public function getAvailableTagsByPattern($pattern)
	{
		$tags = array();
		$reg = '/^' . str_replace('*', '.*', $pattern) . '$/';
		foreach ($this->getAvailableTags() as $tag) 
		{
			if (preg_match($reg, $tag)) {$tags[] = $tag;}
		}
		return $tags;
	}

	/**
	 * @param f_persistentdocument_PersistentDocument $document
	 * @return array
	 */
	function getAffectedTagsForDocument($document)
	{
		$tags = array();
		$model = $document->getPersistentModel();
		$modelsName = array();
		while (true)
		{
			if ($model->isInjectedModel()) {$model = $model->getSourceInjectionModel();}
			$modelsName[$model->getName()] = true;
			if (!$model->hasParent()) {break;}
			$model = f_persistentdocument_PersistentDocumentModel::getInstanceFromDocumentModelName($model->getParentName());
		}
		
		$selfTags = $this->getTags($document);
		$results = array();
		
		foreach ($this->getAvailableTagsInfo() as $tag => $tagInfo) 
		{
			if (isset($modelsName[$tagInfo['component_type']]))
			{
				$results[$tag] = $tagInfo;			
			}
		}
		
		if (count($results))
		{
			$parent = TreeService::getInstance()->getParentDocument($document);
			
			$websiteId = $document->getDocumentService()->getWebsiteId($document);
			$website = $websiteId ? DocumentHelper::getDocumentInstance($websiteId) : null;
			
			$documentId = $document->getId();
			foreach ($results as $tag => $tagInfo)
			{
				if (in_array($tag, $selfTags))
				{
					$tags[] = array('tag' => $tag, 'affected' => true, 'selfAffected' => true);
				}
				elseif ($this->isExclusiveTag($tag))
				{
					if ($this->findDocumentByExclusiveTag($tag))
					{
						$tags[] = array('tag' => $tag, 'affected' => true);
					}
				}
				elseif ($this->isContextualTag($tag))
				{
					// Check that the id is a descendent of the same website than the given document.
					if ($website)
					{
						if ($this->findDocumentByContextualTag($tag, $website))
						{
							$tags[] = array('tag' => $tag, 'affected' => true);
						}
					}
				}
				elseif ($this->isFunctionalTag($tag))
				{
					// Check that the id and the given document has the same parent.
					if ($parent)
					{
						if (count($this->getSiblingDocuments($tag, $document)))
						{
							$tags[] = array('tag' => $tag, 'affected' => true);
						}
					}
				}
			}
		}
		return array('models' => $modelsName, 'tags' => $tags) ;
	}

	/**
	 * This method is used internally to check if a tag is valid or not.
	 * @param string $tag The tag to check.
	 * @return boolean true if $tag is a valid tag, false otherwise.
	 */
	public function isValidTag($tag)
	{
		return ( is_numeric($tag) || ( is_string($tag) && preg_match(self::TAG_REGEXP, $tag) ) );
	}


	/**
	 * This method is used internally to check if a tag is exclusive (can appear
	 * only once in all the tags).
	 * @param string $tag The tag to check.
	 * @return boolean true if $tag is an exclusive tag or false otherwise.
	 */
	public function isExclusiveTag($tag)
	{
		return $this->isValidTag($tag) && substr($tag, 0, 8) === 'default_';
{'fraction_non_alphanumeric': 0.1655660943690719, 'fraction_numerical': 0.0020410613519029897, 'mean_word_length': 3.320539419087137, 'pattern_counts': {'":': 0, '<': 7, '<?xml version=': 0, '>': 80, 'https://': 0, 'lorem ipsum': 0, 'www.': 0, 'xml': 0}, 'pii_count': 0, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 0, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'dir': 'git-commits-cleaned', 'id': '5179985', 'n_tokens_mistral': 3242, 'n_tokens_neox': 2613, 'n_words': 637}