<commit_before><?php
/**
 * Created by IntelliJ IDEA.
 * User: koluch
 * Date: 16/06/16
 * Time: 23:58
 */

namespace app\components;


use Yii;
use yii\data\ActiveDataProvider;
use yii\web\BadRequestHttpException;

trait RestSearchController
{
    public function actions()
    {
        $actions = parent::actions();
        $actions['index']['prepareDataProvider'] = [$this, 'indexPrepareDataProvider'];
        return $actions;
    }

    public function indexPrepareDataProvider()
    {
        function startsWith($haystack, $needle) {
            return $needle === "" || strrpos($haystack, $needle, -strlen($haystack)) !== false;
        }

        function endsWith($haystack, $needle) {
            return $needle === "" || (($temp = strlen($haystack) - strlen($needle)) >= 0 && strpos($haystack, $needle, $temp) !== false);
        }

        $class = $this->modelClass;

        $tableSchema = $class::getTableSchema();

        $table = $tableSchema->fullName;

        $query = $class::find();

        $q = Yii::$app->request->get('q', '');


        if ($q !== '') {
            $conditionArray = ['and'];
            foreach(explode(',', $q) as $cond) {
                if (preg_match('/^(.+):(.+)$/', $cond, $keyValue) !== 1) {
                    throw new BadRequestHttpException("Bad condition format: '$cond' (it should be 'key:value')");
                }

                $key = $keyValue[1];
                $value = $keyValue[2];

                $attrPath = explode(".", $key);
                if (count($attrPath) === 1) {
                    if ($tableSchema->getColumn($key) === null) {
                        throw new BadRequestHttpException("Attribute '$key' doesn't exists");
                    }
                    $attr = "[[$table]].[[$key]]";
                }
                else if(count($attrPath) === 2) {
                    $relation = $attrPath[0];
                    $relationColumn = $attrPath[1];

                    if ($tableSchema->getColumn("${relation}_id") === null) {
                        throw new BadRequestHttpException("Relation '$relation' doesn't exists");
                    }

                    $filteredRelation = array_filter($tableSchema->foreignKeys, function ($foreignKey) use ($relation) {
                        return array_key_exists("${relation}_id", $foreignKey);
                    });

                    if (count($filteredRelation) < 1) {
                        throw new BadRequestHttpException("Relation '$relation' isn't described in DB");
                    }

                    $filteredRelation = $filteredRelation[0];

                    $relationTableSchema = Yii::$app->db->getTableSchema($filteredRelation[0]);
                    if ($relationTableSchema->getColumn($relationColumn) === null) {
                        throw new BadRequestHttpException(
                            "Attribute '$relationColumn' doesn't exists in relation '$relation'"
                        );
                    }

                    $attr = "[[$relation]].[[$relationColumn]]";
                }
                else {
                    throw new BadRequestHttpException("Argument path has a wrong format: '$key'");
                }

                if(strpos($value, '*') !== false) {
                    array_push($conditionArray, ['like', $attr, str_replace('*', '%', $value), false]);
                }
                else if(startsWith($value, '<=') || startsWith($value, '>=')) {
                    array_push($conditionArray, [substr($value, 0, 2), $attr, substr($value, 2)]);
                }
                else if(startsWith($value, '<') || startsWith($value, '>')) {
                    array_push($conditionArray, [substr($value, 0, 1), $attr, substr($value, 1)]);
                }
                else {
                    array_push($conditionArray, [$attr => $value]);
                }
            }
            $query->where($conditionArray);<commit_msg>Add posibility to pass list of values to search query condition<commit_after><?php
/**
 * Created by IntelliJ IDEA.
 * User: koluch
 * Date: 16/06/16
 * Time: 23:58
 */

namespace app\components;


use Yii;
use yii\data\ActiveDataProvider;
use yii\web\BadRequestHttpException;

trait RestSearchController
{
    public function actions()
    {
        $actions = parent::actions();
        $actions['index']['prepareDataProvider'] = [$this, 'indexPrepareDataProvider'];
        return $actions;
    }

    public function indexPrepareDataProvider()
    {
        function startsWith($haystack, $needle) {
            return $needle === "" || strrpos($haystack, $needle, -strlen($haystack)) !== false;
        }

        function endsWith($haystack, $needle) {
            return $needle === "" || (($temp = strlen($haystack) - strlen($needle)) >= 0 && strpos($haystack, $needle, $temp) !== false);
        }

        $class = $this->modelClass;

        $tableSchema = $class::getTableSchema();

        $table = $tableSchema->fullName;

        $query = $class::find();

        $q = Yii::$app->request->get('q', '');


        if ($q !== '') {
            $conditionArray = ['and'];
            foreach(explode(';', $q) as $cond) {
                if (preg_match('/^(.+):(.+)$/', $cond, $keyValue) !== 1) {
                    throw new BadRequestHttpException("Bad condition format: '$cond' (it should be 'key:value')");
                }

                $key = $keyValue[1];
                $value = $keyValue[2];

                $attrPath = explode(".", $key);
                if (count($attrPath) === 1) {
                    if ($tableSchema->getColumn($key) === null) {
                        throw new BadRequestHttpException("Attribute '$key' doesn't exists");
                    }
                    $attr = "[[$table]].[[$key]]";
                }
                else if(count($attrPath) === 2) {
                    $relation = $attrPath[0];
                    $relationColumn = $attrPath[1];

                    if ($tableSchema->getColumn("${relation}_id") === null) {
                        throw new BadRequestHttpException("Relation '$relation' doesn't exists");
                    }

                    $filteredRelation = array_filter($tableSchema->foreignKeys, function ($foreignKey) use ($relation) {
                        return array_key_exists("${relation}_id", $foreignKey);
                    });

                    if (count($filteredRelation) < 1) {
                        throw new BadRequestHttpException("Relation '$relation' isn't described in DB");
                    }

                    $filteredRelation = $filteredRelation[0];

                    $relationTableSchema = Yii::$app->db->getTableSchema($filteredRelation[0]);
                    if ($relationTableSchema->getColumn($relationColumn) === null) {
                        throw new BadRequestHttpException(
                            "Attribute '$relationColumn' doesn't exists in relation '$relation'"
                        );
                    }

                    $attr = "[[$relation]].[[$relationColumn]]";
                }
                else {
                    throw new BadRequestHttpException("Argument path has a wrong format: '$key'");
                }

                if(strpos($value, '*') !== false) {
                    array_push($conditionArray, ['like', $attr, str_replace('*', '%', $value), false]);
                }
                else if(startsWith($value, '<=') || startsWith($value, '>=')) {
                    array_push($conditionArray, [substr($value, 0, 2), $attr, substr($value, 2)]);
                }
                else if(startsWith($value, '<') || startsWith($value, '>')) {
                    array_push($conditionArray, [substr($value, 0, 1), $attr, substr($value, 1)]);
                }
                else {
                    if (preg_match('/^\\[((?:[^,]+,)*(?:[^,]+))\\]$/', $value, $valueList) === 1) {
                        $values = explode(",", $valueList[1]);
                        array_push($conditionArray, [$attr => $values]);
                    }
                    else {
                        array_push($conditionArray, [$attr => $value]);
                    }
                }
            }
            $query->where($conditionArray);
{'fraction_non_alphanumeric': 0.15871107370446075, 'fraction_numerical': 0.00673319706624985, 'mean_word_length': 1.6763191763191763, 'pattern_counts': {'":': 0, '<': 11, '<?xml version=': 0, '>': 34, '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': '2119016', 'n_tokens_mistral': 2314, 'n_tokens_neox': 2098, 'n_words': 437}