<commit_before><?php

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

namespace CRUDlex;

use League\Flysystem\FilesystemInterface;
use League\Flysystem\Util\MimeType;
use Symfony\Component\HttpFoundation\RedirectResponse;
use Symfony\Component\HttpFoundation\Request;
use Symfony\Component\HttpFoundation\Response;
use Symfony\Component\HttpFoundation\Session\Session;
use Symfony\Component\HttpFoundation\StreamedResponse;
use Symfony\Component\Translation\Translator;
use Twig_Environment;


/**
 * This is the Controller offering all CRUD pages.
 *
 * It offers functions for this routes:
 *
 * "/resource/static" serving static resources
 *
 * "/{entity}/create" creation page of the entity
 *
 * "/{entity}" list page of the entity
 *
 * "/{entity}/{id}" details page of a single entity instance
 *
 * "/{entity}/{id}/edit" edit page of a single entity instance
 *
 * "/{entity}/{id}/delete" POST only deletion route for an entity instance
 *
 * "/{entity}/{id}/{field}/file" renders a file field of an entity instance
 *
 * "/{entity}/{id}/{field}/delete" POST only deletion of a file field of an entity instance
 */
class Controller {

    /**
     * Holds the filesystme.
     * @var FilesystemInterface
     */
    protected $filesystem;

    /**
     * Holds the session.
     * @var Session
     */
    protected $session;

    /**
     * Holds the translator.
     * @var Translator
     */
    protected $translator;

    /**
     * Holds the service.
     * @var Service
     */
    protected $service;

    /**
     * Holds the Twig instance.
     * @var Twig_Environment
     */
    protected $twig;

    /**
     * Postprocesses the entity after modification by handling the uploaded
     * files and setting the flash.
     *
     * @param Request $request
     * the current request
     * @param AbstractData $crudData
     * the data instance of the entity
     * @param Entity $instance
     * the entity
     * @param string $entity
     * the name of the entity
     * @param string $mode
     * whether to 'edit' or to 'create' the entity
     *
     * @return null|\Symfony\Component\HttpFoundation\RedirectResponse
     * the HTTP response of this modification
     */
    protected function modifyFilesAndSetFlashBag(Request $request, AbstractData $crudData, Entity $instance, $entity, $mode)
    {
        $id          = $instance->get('id');
        $fileHandler = new FileHandler($this->filesystem, $crudData->getDefinition());
        $result      = $mode == 'edit' ? $fileHandler->updateFiles($crudData, $request, $instance, $entity) : $fileHandler->createFiles($crudData, $request, $instance, $entity);
        if (!$result) {
            return null;
        }
        $this->session->getFlashBag()->add('success', $this->translator->trans('crudlex.'.$mode.'.success', [
            '%label%' => $crudData->getDefinition()->getLabel(),
            '%id%' => $id
        ]));
        return new RedirectResponse($this->service->generateURL('crudShow', ['entity' => $entity, 'id' => $id]));
    }

    /**
     * Sets the flashes of a failed entity modification.
     *
     * @param boolean $optimisticLocking
     * whether the optimistic locking failed
     * @param string $mode
     * the modification mode, either 'create' or 'edit'
     */
    protected function setValidationFailedFlashes($optimisticLocking, $mode)
    {
        $this->session->getFlashBag()->add('danger', $this->translator->trans('crudlex.'.$mode.'.error'));
        if ($optimisticLocking) {
            $this->session->getFlashBag()->add('danger', $this->translator->trans('crudlex.edit.locked'));
        }
    }

    /**
     * Validates and saves the new or updated entity and returns the appropriate HTTP
     * response.
     *
     * @param Request $request
     * the current request
     * @param AbstractData $crudData
     * the data instance of the entity
     * @param Entity $instance
     * the entity
     * @param string $entity
     * the name of the entity
     * @param boolean $edit
     * whether to edit (true) or to create (false) the entity
     *
     * @return Response
     * the HTTP response of this modification
     */
    protected function modifyEntity(Request $request, AbstractData $crudData, Entity $instance, $entity, $edit)
    {
        $fieldErrors = [];
        $mode        = $edit ? 'edit' : 'create';
        if ($request->getMethod() == 'POST') {
            $instance->populateViaRequest($request);
            $validator  = new EntityValidator($instance);
            $validation = $validator->validate($crudData, intval($request->get('version')));

            $fieldErrors = $validation['errors'];
            if (!$validation['valid']) {
                $optimisticLocking = isset($fieldErrors['version']);
                $this->setValidationFailedFlashes($optimisticLocking, $mode);
            } else {
                $modified = $edit ? $crudData->update($instance) : $crudData->create($instance);
                $response = $modified ? $this->modifyFilesAndSetFlashBag($request, $crudData, $instance, $entity, $mode) : false;
                if ($response) {
                    return $response;
                }
                $this->session->getFlashBag()->add('danger', $this->translator->trans('crudlex.'.$mode.'.failed'));
            }
        }

        return $this->twig->render($this->service->getTemplate('template', 'form', $entity), [
            'crud' => $this->service,
            'crudEntity' => $entity,
            'crudData' => $crudData,
            'entity' => $instance,
            'mode' => $mode,
            'fieldErrors' => $fieldErrors,
            'layout' => $this->service->getTemplate('layout', $mode, $entity)
        ]);
    }

    /**
     * Gets the parameters for the redirection after deleting an entity.
     *
     * @param Request $request
     * the current request
     * @param string $entity
     * the entity name
     * @param string $redirectPage
     * reference, where the page to redirect to will be stored
     *
     * @return array<string,string>
     * the parameters of the redirection, entity and id
     */
    protected function getAfterDeleteRedirectParameters(Request $request, $entity, &$redirectPage)
    {
        $redirectPage       = 'crudList';
        $redirectParameters = ['entity' => $entity];
        $redirectEntity     = $request->get('redirectEntity');
        $redirectId         = $request->get('redirectId');
        if ($redirectEntity && $redirectId) {
            $redirectPage       = 'crudShow';
            $redirectParameters = [
                'entity' => $redirectEntity,
                'id' => $redirectId
            ];
        }
        return $redirectParameters;
    }

    /**
     * Builds up the parameters of the list page filters.
     *
     * @param Request $request
     * the current request
     * @param EntityDefinition $definition
     * the current entity definition
     * @param array &$filter
     * will hold a map of fields to request parameters for the filters
     * @param boolean $filterActive
     * reference, will be true if at least one filter is active
     * @param array $filterToUse
     * reference, will hold a map of fields to integers (0 or 1) which boolean filters are active
     * @param array $filterOperators
     * reference, will hold a map of fields to operators for AbstractData::listEntries()
     */
    protected function buildUpListFilter(Request $request, EntityDefinition $definition, &$filter, &$filterActive, &$filterToUse, &$filterOperators)
    {
        foreach ($definition->getFilter() as $filterField) {
            $type                 = $definition->getType($filterField);
            $filter[$filterField] = $request->get('crudFilter'.$filterField);
            if ($filter[$filterField]) {
                $filterActive                  = true;
                $filterToUse[$filterField]     = $filter[$filterField];
                $filterOperators[$filterField] = '=';
                if ($type === 'boolean') {
                    $filterToUse[$filterField] = $filter[$filterField] == 'true' ? 1 : 0;
                } else if ($type === 'reference') {
                    $filter[$filterField] = ['id' => $filter[$filterField]];
                } else if ($type === 'many') {
                    $filter[$filterField] = array_map(function($value) {
                        return ['id' => $value];
                    }, $filter[$filterField]);
                    $filterToUse[$filterField] = $filter[$filterField];
                } else if (in_array($type, ['text', 'multiline', 'fixed'])) {
                    $filterToUse[$filterField]     = '%'.$filter[$filterField].'%';
                    $filterOperators[$filterField] = 'LIKE';
                }
            }
        }
    }

    /**
     * Controller constructor.
     *
     * @param Service $service
     * the CRUDlex service
     * @param FilesystemInterface $filesystem
     * the used filesystem
     * @param Twig_Environment $twig
     * the Twig environment
     * @param Session $session
     * the session service
     * @param Translator $translator
     * the translation service
     */
    public function __construct(Service $service, FilesystemInterface $filesystem, Twig_Environment $twig, Session $session, Translator $translator)
    {
        $this->service    = $service;
        $this->filesystem = $filesystem;
        $this->twig       = $twig;
        $this->session    = $session;
        $this->translator = $translator;
    }
<commit_msg>using the symfony interfaces, not the actual implementations<commit_after><?php

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

namespace CRUDlex;

use League\Flysystem\FilesystemInterface;
use League\Flysystem\Util\MimeType;
use Symfony\Component\HttpFoundation\RedirectResponse;
use Symfony\Component\HttpFoundation\Request;
use Symfony\Component\HttpFoundation\Response;
use Symfony\Component\HttpFoundation\Session\SessionInterface;
use Symfony\Component\HttpFoundation\StreamedResponse;
use Symfony\Component\Translation\TranslatorInterface;
use Twig_Environment;


/**
 * This is the Controller offering all CRUD pages.
 *
 * It offers functions for this routes:
 *
 * "/resource/static" serving static resources
 *
 * "/{entity}/create" creation page of the entity
 *
 * "/{entity}" list page of the entity
 *
 * "/{entity}/{id}" details page of a single entity instance
 *
 * "/{entity}/{id}/edit" edit page of a single entity instance
 *
 * "/{entity}/{id}/delete" POST only deletion route for an entity instance
 *
 * "/{entity}/{id}/{field}/file" renders a file field of an entity instance
 *
 * "/{entity}/{id}/{field}/delete" POST only deletion of a file field of an entity instance
 */
class Controller {

    /**
     * Holds the filesystme.
     * @var FilesystemInterface
     */
    protected $filesystem;

    /**
     * Holds the session.
     * @var SessionInterface
     */
    protected $session;

    /**
     * Holds the translator.
     * @var TranslatorInterface
     */
    protected $translator;

    /**
     * Holds the service.
     * @var Service
     */
    protected $service;

    /**
     * Holds the Twig instance.
     * @var Twig_Environment
     */
    protected $twig;

    /**
     * Postprocesses the entity after modification by handling the uploaded
     * files and setting the flash.
     *
     * @param Request $request
     * the current request
     * @param AbstractData $crudData
     * the data instance of the entity
     * @param Entity $instance
     * the entity
     * @param string $entity
     * the name of the entity
     * @param string $mode
     * whether to 'edit' or to 'create' the entity
     *
     * @return null|\Symfony\Component\HttpFoundation\RedirectResponse
     * the HTTP response of this modification
     */
    protected function modifyFilesAndSetFlashBag(Request $request, AbstractData $crudData, Entity $instance, $entity, $mode)
    {
        $id          = $instance->get('id');
        $fileHandler = new FileHandler($this->filesystem, $crudData->getDefinition());
        $result      = $mode == 'edit' ? $fileHandler->updateFiles($crudData, $request, $instance, $entity) : $fileHandler->createFiles($crudData, $request, $instance, $entity);
        if (!$result) {
            return null;
        }
        $this->session->getFlashBag()->add('success', $this->translator->trans('crudlex.'.$mode.'.success', [
            '%label%' => $crudData->getDefinition()->getLabel(),
            '%id%' => $id
        ]));
        return new RedirectResponse($this->service->generateURL('crudShow', ['entity' => $entity, 'id' => $id]));
    }

    /**
     * Sets the flashes of a failed entity modification.
     *
     * @param boolean $optimisticLocking
     * whether the optimistic locking failed
     * @param string $mode
     * the modification mode, either 'create' or 'edit'
     */
    protected function setValidationFailedFlashes($optimisticLocking, $mode)
    {
        $this->session->getFlashBag()->add('danger', $this->translator->trans('crudlex.'.$mode.'.error'));
        if ($optimisticLocking) {
            $this->session->getFlashBag()->add('danger', $this->translator->trans('crudlex.edit.locked'));
        }
    }

    /**
     * Validates and saves the new or updated entity and returns the appropriate HTTP
     * response.
     *
     * @param Request $request
     * the current request
     * @param AbstractData $crudData
     * the data instance of the entity
     * @param Entity $instance
     * the entity
     * @param string $entity
     * the name of the entity
     * @param boolean $edit
     * whether to edit (true) or to create (false) the entity
     *
     * @return Response
     * the HTTP response of this modification
     */
    protected function modifyEntity(Request $request, AbstractData $crudData, Entity $instance, $entity, $edit)
    {
        $fieldErrors = [];
        $mode        = $edit ? 'edit' : 'create';
        if ($request->getMethod() == 'POST') {
            $instance->populateViaRequest($request);
            $validator  = new EntityValidator($instance);
            $validation = $validator->validate($crudData, intval($request->get('version')));

            $fieldErrors = $validation['errors'];
            if (!$validation['valid']) {
                $optimisticLocking = isset($fieldErrors['version']);
                $this->setValidationFailedFlashes($optimisticLocking, $mode);
            } else {
                $modified = $edit ? $crudData->update($instance) : $crudData->create($instance);
                $response = $modified ? $this->modifyFilesAndSetFlashBag($request, $crudData, $instance, $entity, $mode) : false;
                if ($response) {
                    return $response;
                }
                $this->session->getFlashBag()->add('danger', $this->translator->trans('crudlex.'.$mode.'.failed'));
            }
        }

        return $this->twig->render($this->service->getTemplate('template', 'form', $entity), [
            'crud' => $this->service,
            'crudEntity' => $entity,
            'crudData' => $crudData,
            'entity' => $instance,
            'mode' => $mode,
            'fieldErrors' => $fieldErrors,
            'layout' => $this->service->getTemplate('layout', $mode, $entity)
        ]);
    }

    /**
     * Gets the parameters for the redirection after deleting an entity.
     *
     * @param Request $request
     * the current request
     * @param string $entity
     * the entity name
     * @param string $redirectPage
     * reference, where the page to redirect to will be stored
     *
     * @return array<string,string>
     * the parameters of the redirection, entity and id
     */
    protected function getAfterDeleteRedirectParameters(Request $request, $entity, &$redirectPage)
    {
        $redirectPage       = 'crudList';
        $redirectParameters = ['entity' => $entity];
        $redirectEntity     = $request->get('redirectEntity');
        $redirectId         = $request->get('redirectId');
        if ($redirectEntity && $redirectId) {
            $redirectPage       = 'crudShow';
            $redirectParameters = [
                'entity' => $redirectEntity,
                'id' => $redirectId
            ];
        }
        return $redirectParameters;
    }

    /**
     * Builds up the parameters of the list page filters.
     *
     * @param Request $request
     * the current request
     * @param EntityDefinition $definition
     * the current entity definition
     * @param array &$filter
     * will hold a map of fields to request parameters for the filters
     * @param boolean $filterActive
     * reference, will be true if at least one filter is active
     * @param array $filterToUse
     * reference, will hold a map of fields to integers (0 or 1) which boolean filters are active
     * @param array $filterOperators
     * reference, will hold a map of fields to operators for AbstractData::listEntries()
     */
    protected function buildUpListFilter(Request $request, EntityDefinition $definition, &$filter, &$filterActive, &$filterToUse, &$filterOperators)
    {
        foreach ($definition->getFilter() as $filterField) {
            $type                 = $definition->getType($filterField);
            $filter[$filterField] = $request->get('crudFilter'.$filterField);
            if ($filter[$filterField]) {
                $filterActive                  = true;
                $filterToUse[$filterField]     = $filter[$filterField];
                $filterOperators[$filterField] = '=';
                if ($type === 'boolean') {
                    $filterToUse[$filterField] = $filter[$filterField] == 'true' ? 1 : 0;
                } else if ($type === 'reference') {
                    $filter[$filterField] = ['id' => $filter[$filterField]];
                } else if ($type === 'many') {
                    $filter[$filterField] = array_map(function($value) {
                        return ['id' => $value];
                    }, $filter[$filterField]);
                    $filterToUse[$filterField] = $filter[$filterField];
                } else if (in_array($type, ['text', 'multiline', 'fixed'])) {
                    $filterToUse[$filterField]     = '%'.$filter[$filterField].'%';
                    $filterOperators[$filterField] = 'LIKE';
                }
            }
        }
    }

    /**
     * Controller constructor.
     *
     * @param Service $service
     * the CRUDlex service
     * @param FilesystemInterface $filesystem
     * the used filesystem
     * @param Twig_Environment $twig
     * the Twig environment
     * @param SessionInterface $session
     * the session service
     * @param TranslatorInterface $translator
     * the translation service
     */
    public function __construct(Service $service, FilesystemInterface $filesystem, Twig_Environment $twig, SessionInterface $session, TranslatorInterface $translator)
    {
        $this->service    = $service;
        $this->filesystem = $filesystem;
        $this->twig       = $twig;
        $this->session    = $session;
        $this->translator = $translator;
    }

{'fraction_non_alphanumeric': 0.12753460340160375, 'fraction_numerical': 0.0004086010521477093, 'mean_word_length': 2.3840304182509504, 'pattern_counts': {'":': 0, '<': 13, '<?xml version=': 0, '>': 151, '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': '6784685', 'n_tokens_mistral': 5314, 'n_tokens_neox': 5173, 'n_words': 1435}