<commit_before><?php

namespace Rutorika\Sortable;

use Illuminate\Database\Eloquent\Model;
use Illuminate\Routing\Controller;
use Illuminate\Http\Request;

class SortableController extends Controller
{
    public function sort(Request $request)
    {
        $sortableEntities = app('config')->get('sortable.entities', []);

        $validator = $this->getValidator($sortableEntities, $request);

        if ($validator->passes()) {
            $relation = false;

            $entityConfig = $sortableEntities[$request->input('entityName')];

            if (is_array($entityConfig)) {
                $entityClass = $entityConfig['entity'];
                $relation = !empty($entityConfig['relation']) ? $entityConfig['relation'] : false;
            } else {
                $entityClass = $entityConfig;
            }

            if (!$relation) {
                /** @var SortableTrait|Model $entity */
                $entity = $entityClass::find($request->input('id'));
                $postionEntity = $entityClass::find($request->input('positionEntityId'));
                switch ($request->input('type')) {
                    case 'moveAfter':
                        $entity->moveAfter($postionEntity);
                        break;
                    case 'moveBefore':
                        $entity->moveBefore($postionEntity);
                        break;
                }
            } else {
                $parentEntity = $entityClass::find($request->input('parentId'));

                $entity = $parentEntity->$relation()->find($request->input('id'));
                $postionEntity = $parentEntity->$relation()->find($request->input('positionEntityId'));

                switch ($request->input('type')) {
                    case 'moveAfter':
                        $parentEntity->$relation()->moveAfter($entity, $postionEntity);
                        break;
                    case 'moveBefore':
                        $parentEntity->$relation()->moveBefore($entity, $postionEntity);
                        break;
                }
            }

            return [
                'success' => true,
            ];
        } else {
            return [
                'success' => false,
                'errors' => $validator->errors(),
                'failed' => $validator->failed(),
            ];
        }
    }

    /**
     * @param array   $sortableEntities
     * @param Request $request
     *
     * @return mixed
     */
    protected function getValidator($sortableEntities, $request)
    {
        /** @var  \Illuminate\Validation\Factory $validator */
        $validator = app('validator');

        $rules = [
            'type' => ['required', 'in:moveAfter,moveBefore'],
            'entityName' => ['required', 'in:' . implode(',', array_keys($sortableEntities))],
            'id' => 'required|numeric',
            'positionEntityId' => 'required|numeric',
        ];

        /** @var Model|bool $entityClass */
        $entityClass = false;
        $relation = false;

        if (array_key_exists($request->input('entityName'), $sortableEntities)) {
            $entityConfig = $sortableEntities[$request->input('entityName')];

            if (is_array($entityConfig)) {
                $entityClass = $entityConfig['entity'];
                $relation = !empty($entityConfig['relation']) ? $entityConfig['relation'] : false;
            } else {
                $entityClass = $entityConfig;
            }
        }

        if ($relation) {
            $rules['parentId'] = 'required|numeric';
        }

        if (!class_exists($entityClass)) {
            $rules['entityClass'] = 'required'; // fake rule for not exist field
        } else {
            $tableName = with(new $entityClass())->getTable();
            $primaryKey = with(new $entityClass())->getKeyName();

            if (!$relation) {
                $rules['id'] .= '|exists:' . $tableName . ',' . $primaryKey;
                $rules['positionEntityId'] .= '|exists:' . $tableName . ',' . $primaryKey;
            } else {
                $rules['parentId'] .= '|exists:' . $tableName . ',' . $primaryKey;

                /** @var BelongsToSortedMany $relationObject */
                $relationObject = with(new $entityClass())->$relation();
                $pivotTable = $relationObject->getTable();

                $rules['id'] .= '|exists:' . $pivotTable . ',' . $relationObject->getOtherKey() . ',' . $relationObject->getForeignKey() . ',' . $request->input('parentId');
                $rules['positionEntityId'] .= '|exists:' . $pivotTable . ',' . $relationObject->getOtherKey() . ',' . $relationObject->getForeignKey() . ',' . $request->input('parentId');
            }<commit_msg>Remove numeric rule for id and positionEntityId [11]<commit_after><?php

namespace Rutorika\Sortable;

use Illuminate\Database\Eloquent\Model;
use Illuminate\Routing\Controller;
use Illuminate\Http\Request;

class SortableController extends Controller
{
    public function sort(Request $request)
    {
        $sortableEntities = app('config')->get('sortable.entities', []);

        $validator = $this->getValidator($sortableEntities, $request);

        if ($validator->passes()) {
            $relation = false;

            $entityConfig = $sortableEntities[$request->input('entityName')];

            if (is_array($entityConfig)) {
                $entityClass = $entityConfig['entity'];
                $relation = !empty($entityConfig['relation']) ? $entityConfig['relation'] : false;
            } else {
                $entityClass = $entityConfig;
            }

            if (!$relation) {
                /** @var SortableTrait|Model $entity */
                $entity = $entityClass::find($request->input('id'));
                $postionEntity = $entityClass::find($request->input('positionEntityId'));
                switch ($request->input('type')) {
                    case 'moveAfter':
                        $entity->moveAfter($postionEntity);
                        break;
                    case 'moveBefore':
                        $entity->moveBefore($postionEntity);
                        break;
                }
            } else {
                $parentEntity = $entityClass::find($request->input('parentId'));

                $entity = $parentEntity->$relation()->find($request->input('id'));
                $postionEntity = $parentEntity->$relation()->find($request->input('positionEntityId'));

                switch ($request->input('type')) {
                    case 'moveAfter':
                        $parentEntity->$relation()->moveAfter($entity, $postionEntity);
                        break;
                    case 'moveBefore':
                        $parentEntity->$relation()->moveBefore($entity, $postionEntity);
                        break;
                }
            }

            return [
                'success' => true,
            ];
        } else {
            return [
                'success' => false,
                'errors' => $validator->errors(),
                'failed' => $validator->failed(),
            ];
        }
    }

    /**
     * @param array   $sortableEntities
     * @param Request $request
     *
     * @return mixed
     */
    protected function getValidator($sortableEntities, $request)
    {
        /** @var  \Illuminate\Validation\Factory $validator */
        $validator = app('validator');

        $rules = [
            'type' => ['required', 'in:moveAfter,moveBefore'],
            'entityName' => ['required', 'in:' . implode(',', array_keys($sortableEntities))],
            'id' => 'required',
            'positionEntityId' => 'required',
        ];

        /** @var Model|bool $entityClass */
        $entityClass = false;
        $relation = false;

        if (array_key_exists($request->input('entityName'), $sortableEntities)) {
            $entityConfig = $sortableEntities[$request->input('entityName')];

            if (is_array($entityConfig)) {
                $entityClass = $entityConfig['entity'];
                $relation = !empty($entityConfig['relation']) ? $entityConfig['relation'] : false;
            } else {
                $entityClass = $entityConfig;
            }
        }

        if ($relation) {
            $rules['parentId'] = 'required';
        }

        if (!class_exists($entityClass)) {
            $rules['entityClass'] = 'required'; // fake rule for not exist field
        } else {
            $tableName = with(new $entityClass())->getTable();
            $primaryKey = with(new $entityClass())->getKeyName();

            if (!$relation) {
                $rules['id'] .= '|exists:' . $tableName . ',' . $primaryKey;
                $rules['positionEntityId'] .= '|exists:' . $tableName . ',' . $primaryKey;
            } else {
                $rules['parentId'] .= '|exists:' . $tableName . ',' . $primaryKey;

                /** @var BelongsToSortedMany $relationObject */
                $relationObject = with(new $entityClass())->$relation();
                $pivotTable = $relationObject->getTable();

                $rules['id'] .= '|exists:' . $pivotTable . ',' . $relationObject->getOtherKey() . ',' . $relationObject->getForeignKey() . ',' . $request->input('parentId');
                $rules['positionEntityId'] .= '|exists:' . $pivotTable . ',' . $relationObject->getOtherKey() . ',' . $relationObject->getForeignKey() . ',' . $request->input('parentId');
            }
{'fraction_non_alphanumeric': 0.15938059622880016, 'fraction_numerical': 0.00021068155482987464, 'mean_word_length': 1.8222354340071343, 'pattern_counts': {'":': 0, '<': 5, '<?xml version=': 0, '>': 89, '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': '1482', 'n_tokens_mistral': 2459, 'n_tokens_neox': 2399, 'n_words': 401}