<commit_before><?php

/**
 * This file is part of the Arachne Verifier extenstion
 *
 * Copyright (c) <NAME> (<EMAIL>)
 *
 * For the full copyright and license information, please view the file license.md that was distributed with this source code.
 */

namespace Arachne\Verifier;

/**
 * @author <NAME>
 */
class Verifier extends \Nette\Object
{

	/** @var \Nette\Application\IPresenterFactory */
	protected $presenterFactory;

	/** @var \Doctrine\Common\Annotations\Reader */
	protected $reader;

	/** @var \Nette\DI\Container */
	protected $container;

	/**
	 * @param \Doctrine\Common\Annotations\Reader $reader
	 * @param \Nette\DI\Container $container $container
	 * @param \Nette\Application\IPresenterFactory $presenterFactory
	 */
	public function __construct(\Doctrine\Common\Annotations\Reader $reader, \Nette\DI\Container $container, \Nette\Application\IPresenterFactory $presenterFactory)
	{
		$this->reader = $reader;
		$this->container = $container;
		$this->presenterFactory = $presenterFactory;
	}

	/**
	 * @param \ReflectionClass|\ReflectionMethod $annotations
	 * @param \Nette\Application\Request $request
	 * @throws \Nette\Application\ForbiddenRequestException
	 */
	public function checkAnnotations(\Reflector $reflection, \Nette\Application\Request $request)
	{
		if ($reflection instanceof \ReflectionMethod) {
			$requirements = $this->reader->getMethodAnnotation($reflection, 'Arachne\Verifier\Requirements');
		} elseif ($reflection instanceof \ReflectionClass) {
			$requirements = $this->reader->getClassAnnotation($reflection, 'Arachne\Verifier\Requirements');
		} else {
			throw new InvalidArgumentException('Reflection must be an instance of either \ReflectionMethod or \ReflectionClass.');
		}

		static $handlers = [];
		if ($requirements !== NULL) {
			foreach ($requirements->rules as $rule) {
				$class = $rule->getHandlerClass();
				if (!isset($handlers[$class])) {
					$handlers[$class] = $this->container->getByType($class);
					if (!$handlers[$class] instanceof IAnnotationHandler) {
						throw new InvalidStateException('Class \'' . get_class($handlers[$class]) . '\' does not implement \Arachne\Verifier\IAnnotationHandler interface.');
					}
				}
				$handlers[$class]->checkAnnotation($rule, $request);
			}
		}
	}

	/**
	 * @param \Nette\Application\Request $request
	 * @return bool
	 */
	public function isLinkAvailable(\Nette\Application\Request $request)
	{
		$presenter = $request->getPresenterName();
		$parameters = $request->getParameters();
		$presenterReflection = new \Nette\Application\UI\PresenterComponentReflection($this->presenterFactory->getPresenterClass($presenter));

		try {
			// Presenter requirements
			$this->checkAnnotations($presenterReflection, $request);

			// Action requirements
			$action = $parameters[\Nette\Application\UI\Presenter::ACTION_KEY];
			$method = 'action' . $action;
			$reflection = $presenterReflection->hasCallableMethod($method) ? $presenterReflection->getMethod($method) : NULL;
			if (!$reflection) {
				$method = 'render' . $action;
				$reflection = $presenterReflection->hasCallableMethod($method) ? $presenterReflection->getMethod($method) : NULL;
			}
			if ($reflection) {
				$this->checkAnnotations($reflection, $request);
			}<commit_msg>Never again use static variables inside methods!<commit_after><?php

/**
 * This file is part of the Arachne Verifier extenstion
 *
 * Copyright (c) <NAME> (<EMAIL>)
 *
 * For the full copyright and license information, please view the file license.md that was distributed with this source code.
 */

namespace Arachne\Verifier;

/**
 * @author <NAME>
 */
class Verifier extends \Nette\Object
{

	/** @var \Nette\Application\IPresenterFactory */
	protected $presenterFactory;

	/** @var \Doctrine\Common\Annotations\Reader */
	protected $reader;

	/** @var \Nette\DI\Container */
	protected $container;

	/** @var array<\Arachne\Verifier\IAnnotationHandler> */
	private $handlers;

	/**
	 * @param \Doctrine\Common\Annotations\Reader $reader
	 * @param \Nette\DI\Container $container $container
	 * @param \Nette\Application\IPresenterFactory $presenterFactory
	 */
	public function __construct(\Doctrine\Common\Annotations\Reader $reader, \Nette\DI\Container $container, \Nette\Application\IPresenterFactory $presenterFactory)
	{
		$this->reader = $reader;
		$this->container = $container;
		$this->presenterFactory = $presenterFactory;
		$this->handlers = [];
	}

	/**
	 * @param \ReflectionClass|\ReflectionMethod $annotations
	 * @param \Nette\Application\Request $request
	 * @throws \Nette\Application\ForbiddenRequestException
	 */
	public function checkAnnotations(\Reflector $reflection, \Nette\Application\Request $request)
	{
		if ($reflection instanceof \ReflectionMethod) {
			$requirements = $this->reader->getMethodAnnotation($reflection, 'Arachne\Verifier\Requirements');
		} elseif ($reflection instanceof \ReflectionClass) {
			$requirements = $this->reader->getClassAnnotation($reflection, 'Arachne\Verifier\Requirements');
		} else {
			throw new InvalidArgumentException('Reflection must be an instance of either \ReflectionMethod or \ReflectionClass.');
		}

		if ($requirements !== NULL) {
			foreach ($requirements->rules as $rule) {
				$class = $rule->getHandlerClass();
				if (!isset($this->handlers[$class])) {
					$this->handlers[$class] = $this->container->getByType($class);
					if (!$this->handlers[$class] instanceof IAnnotationHandler) {
						throw new InvalidStateException('Class \'' . get_class($this->handlers[$class]) . '\' does not implement \Arachne\Verifier\IAnnotationHandler interface.');
					}
				}
				$this->handlers[$class]->checkAnnotation($rule, $request);
			}
		}
	}

	/**
	 * @param \Nette\Application\Request $request
	 * @return bool
	 */
	public function isLinkAvailable(\Nette\Application\Request $request)
	{
		$presenter = $request->getPresenterName();
		$parameters = $request->getParameters();
		$presenterReflection = new \Nette\Application\UI\PresenterComponentReflection($this->presenterFactory->getPresenterClass($presenter));

		try {
			// Presenter requirements
			$this->checkAnnotations($presenterReflection, $request);

			// Action requirements
			$action = $parameters[\Nette\Application\UI\Presenter::ACTION_KEY];
			$method = 'action' . $action;
			$reflection = $presenterReflection->hasCallableMethod($method) ? $presenterReflection->getMethod($method) : NULL;
			if (!$reflection) {
				$method = 'render' . $action;
				$reflection = $presenterReflection->hasCallableMethod($method) ? $presenterReflection->getMethod($method) : NULL;
			}
			if ($reflection) {
				$this->checkAnnotations($reflection, $request);
			}
{'fraction_non_alphanumeric': 0.14440108075652958, 'fraction_numerical': 0.0, 'mean_word_length': 4.618043844856661, 'pattern_counts': {'":': 0, '<': 12, '<?xml version=': 0, '>': 60, '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': '2211195', 'n_tokens_mistral': 2124, 'n_tokens_neox': 1931, 'n_words': 395}