<commit_before><?php

namespace CatLab\Charon\Laravel\Controllers;

use CatLab\Charon\Collections\ResourceCollection;
use CatLab\Charon\Enums\Action;
use CatLab\Charon\Exceptions\ResourceException;
use CatLab\Charon\Interfaces\Context;
use CatLab\Charon\Interfaces\ResourceDefinition;
use CatLab\Charon\Laravel\Database\Model;
use CatLab\Charon\Exceptions\EntityNotFoundException;
use CatLab\Charon\Laravel\Models\ResourceResponse;
use CatLab\Charon\Models\RESTResource;
use CatLab\Charon\Laravel\Contracts\Response as ResponseContract;
use CatLab\Requirements\Exceptions\RequirementValidationException;
use CatLab\Requirements\Exceptions\ResourceValidationException;
use CatLab\Requirements\Exceptions\ValidationException;
use Illuminate\Auth\Access\AuthorizationException;
use Illuminate\Foundation\Auth\Access\AuthorizesRequests;
use Illuminate\Http\Request;
use Symfony\Component\HttpFoundation\Response;

/**
 * Trait CRUDController
 *
 * This trait contains some basic functionality to easily set up a laravel crud controller.
 * Any class using this trait must also use the ResourceController trait.
 *
 * @package CatLab\Charon\Laravel\Controllers
 */
trait CrudController
{
    /*
     * Required methods
     */

    abstract function getResourceResponse($data, Context $context  = null): ResponseContract;

    abstract function getContext($action = Action::VIEW, $parameters = []) : Context;
    abstract function getResourceDefinition(): ResourceDefinition;

    abstract function getResources($queryBuilder, Context $context, $resourceDefinition = null, $records = null);

    abstract function bodyToResource(Context $context, $resourceDefinition = null) : RESTResource;
    abstract function bodyToResources(Context $context, $resourceDefinition = null) : ResourceCollection;

    abstract function getValidationErrorResponse(ResourceValidationException $e);
    abstract function notFound($id, $resource);
    abstract function toEntity(RESTResource $resource, Context $context, $existingEntity = null, $resourceDefinition = null, $entityFactory = null);

    abstract function toResources($entities, Context $context, $resourceDefinition = null) : ResourceCollection;
    abstract function toResource($entity, Context $context, $resourceDefinition = null) : RESTResource;

    use AuthorizesRequests {
        authorize as laravelAuthorize;
    }

    /**
     * @var Request
     */
    protected $request;

    /**
     * OrganisationController constructor.
     * @throws ResourceException
     */
    public function __construct()
    {
        if (!defined('static::RESOURCE_DEFINITION')) {
            throw new ResourceException("All classes using CrudController must define a constant called RESOURCE_DEFINITION. " . get_class($this) . ' does not have this constant.');
        }

        parent::__construct(static::RESOURCE_DEFINITION);
    }

    /**
     * @param Request $request
     * @return Response
     * @throws AuthorizationException
     */
    public function index(Request $request)
    {
        $this->request = $request;

        $this->authorizeIndex($request);
        $context = $this->getContext(Action::INDEX);

        $resources = $this->getResources($this->getIndexQuery($request), $context);
        return $this->getResourceResponse($resources, $context);
    }

    /**
     * View an entity
     * @param Request $request
     * @return Response
     * @throws AuthorizationException
     */
    public function view(Request $request)
    {
        $this->request = $request;

        $entity = $this->findEntity($request);
        $this->authorizeView($request, $entity);

        return $this->createViewEntityResponse($entity);
    }

    /**
     * Create a new entity
     * @param Request $request
     * @return Response
     * @throws RequirementValidationException
     * @throws AuthorizationException
     * @throws ValidationException
     */
    public function store(Request $request)
    {
        $this->request = $request;

        $this->authorizeCreate($request);

        $writeContext = $this->getContext(Action::CREATE);
        $inputResources = $this->bodyToResources($writeContext);

        // first validate all resources
        foreach ($inputResources as $inputResource) {
            try {
                $inputResource->validate($writeContext);
            } catch (ResourceValidationException $e) {
                return $this->getValidationErrorResponse($e);
            }
        }

        $createdResources = new ResourceCollection();

        $readContext = $this->getContext(Action::VIEW);

        // now save all resources
        foreach ($inputResources as $inputResource) {
            $entity = $this->toEntity($inputResource, $writeContext);

            // Save the entity
            $entity = $this->saveEntity($request, $entity);

            $createdResources->add($this->toResource($entity, $readContext));
        }

        \Log::warning($inputResources->getMeta('bulk'));

        // Turn back into a resource<commit_msg>And also remove the log.<commit_after><?php

namespace CatLab\Charon\Laravel\Controllers;

use CatLab\Charon\Collections\ResourceCollection;
use CatLab\Charon\Enums\Action;
use CatLab\Charon\Exceptions\ResourceException;
use CatLab\Charon\Interfaces\Context;
use CatLab\Charon\Interfaces\ResourceDefinition;
use CatLab\Charon\Laravel\Database\Model;
use CatLab\Charon\Exceptions\EntityNotFoundException;
use CatLab\Charon\Laravel\Models\ResourceResponse;
use CatLab\Charon\Models\RESTResource;
use CatLab\Charon\Laravel\Contracts\Response as ResponseContract;
use CatLab\Requirements\Exceptions\RequirementValidationException;
use CatLab\Requirements\Exceptions\ResourceValidationException;
use CatLab\Requirements\Exceptions\ValidationException;
use Illuminate\Auth\Access\AuthorizationException;
use Illuminate\Foundation\Auth\Access\AuthorizesRequests;
use Illuminate\Http\Request;
use Symfony\Component\HttpFoundation\Response;

/**
 * Trait CRUDController
 *
 * This trait contains some basic functionality to easily set up a laravel crud controller.
 * Any class using this trait must also use the ResourceController trait.
 *
 * @package CatLab\Charon\Laravel\Controllers
 */
trait CrudController
{
    /*
     * Required methods
     */

    abstract function getResourceResponse($data, Context $context  = null): ResponseContract;

    abstract function getContext($action = Action::VIEW, $parameters = []) : Context;
    abstract function getResourceDefinition(): ResourceDefinition;

    abstract function getResources($queryBuilder, Context $context, $resourceDefinition = null, $records = null);

    abstract function bodyToResource(Context $context, $resourceDefinition = null) : RESTResource;
    abstract function bodyToResources(Context $context, $resourceDefinition = null) : ResourceCollection;

    abstract function getValidationErrorResponse(ResourceValidationException $e);
    abstract function notFound($id, $resource);
    abstract function toEntity(RESTResource $resource, Context $context, $existingEntity = null, $resourceDefinition = null, $entityFactory = null);

    abstract function toResources($entities, Context $context, $resourceDefinition = null) : ResourceCollection;
    abstract function toResource($entity, Context $context, $resourceDefinition = null) : RESTResource;

    use AuthorizesRequests {
        authorize as laravelAuthorize;
    }

    /**
     * @var Request
     */
    protected $request;

    /**
     * OrganisationController constructor.
     * @throws ResourceException
     */
    public function __construct()
    {
        if (!defined('static::RESOURCE_DEFINITION')) {
            throw new ResourceException("All classes using CrudController must define a constant called RESOURCE_DEFINITION. " . get_class($this) . ' does not have this constant.');
        }

        parent::__construct(static::RESOURCE_DEFINITION);
    }

    /**
     * @param Request $request
     * @return Response
     * @throws AuthorizationException
     */
    public function index(Request $request)
    {
        $this->request = $request;

        $this->authorizeIndex($request);
        $context = $this->getContext(Action::INDEX);

        $resources = $this->getResources($this->getIndexQuery($request), $context);
        return $this->getResourceResponse($resources, $context);
    }

    /**
     * View an entity
     * @param Request $request
     * @return Response
     * @throws AuthorizationException
     */
    public function view(Request $request)
    {
        $this->request = $request;

        $entity = $this->findEntity($request);
        $this->authorizeView($request, $entity);

        return $this->createViewEntityResponse($entity);
    }

    /**
     * Create a new entity
     * @param Request $request
     * @return Response
     * @throws RequirementValidationException
     * @throws AuthorizationException
     * @throws ValidationException
     */
    public function store(Request $request)
    {
        $this->request = $request;

        $this->authorizeCreate($request);

        $writeContext = $this->getContext(Action::CREATE);
        $inputResources = $this->bodyToResources($writeContext);

        // first validate all resources
        foreach ($inputResources as $inputResource) {
            try {
                $inputResource->validate($writeContext);
            } catch (ResourceValidationException $e) {
                return $this->getValidationErrorResponse($e);
            }
        }

        $createdResources = new ResourceCollection();

        $readContext = $this->getContext(Action::VIEW);

        // now save all resources
        foreach ($inputResources as $inputResource) {
            $entity = $this->toEntity($inputResource, $writeContext);

            // Save the entity
            $entity = $this->saveEntity($request, $entity);

            $createdResources->add($this->toResource($entity, $readContext));
        }

        // Turn back into a resource
{'fraction_non_alphanumeric': 0.10455951311982441, 'fraction_numerical': 0.0, 'mean_word_length': 3.4590747330960854, 'pattern_counts': {'":': 0, '<': 5, '<?xml version=': 0, '>': 46, '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': '2345036', 'n_tokens_mistral': 2594, 'n_tokens_neox': 2508, 'n_words': 602}