rappasoft / laravel-livewire-tables

A dynamic table component for Laravel Livewire
https://rappasoft.com/docs/laravel-livewire-tables/v2/introduction
MIT License
1.75k stars 330 forks source link

Searching stopped working since v1.13.0 #480

Closed qwasyx0 closed 2 years ago

qwasyx0 commented 2 years ago

Did an update from 1.8.0 to newest version and I'm getting this error when using the Search functionality:

strtolower(): Argument #1 ($string) must be of type string, stdClass given

I downgraded down to 1.13.0. which is the last version searching is working, v1.14+ gives me this error, no code changed, just re-published assets as said in installation guide.

rappasoft commented 2 years ago

Does it tell you what file and line? I don't see strtolower used in the codebase.

qwasyx0 commented 2 years ago

Stacktrace says this, from bottom to top:

error is here: return $this->applyPagination($this->rowsQuery());

Rappasoft\LaravelLivewireTables\DataTableComponent::getRowsProperty
C:\prace\projekty\sasreport\vendor\rappasoft\laravel-livewire-tables\src\DataTableComponent.php:173

    /**

     * Get the rows paginated collection that will be returned to the view.

     *

     * @return Builder[]|\Illuminate\Database\Eloquent\Collection|mixed

     */

    public function getRowsProperty()

    {

        if ($this->paginationEnabled) {

            return $this->applyPagination($this->rowsQuery());

        }

        return $this->rowsQuery()->get();

    }

Next error is here: $query = $this->applySearchFilter($query);

Rappasoft\LaravelLivewireTables\DataTableComponent::rowsQuery
C:\prace\projekty\sasreport\vendor\rappasoft\laravel-livewire-tables\src\DataTableComponent.php:159

  public function rowsQuery()

    {

        $this->cleanFilters();

        $query = $this->query();

        if (method_exists($this, 'applySorting')) {

            $query = $this->applySorting($query);

        }

        if (method_exists($this, 'applySearchFilter')) {

            $query = $this->applySearchFilter($query);

        }

        return $query;

    }

Next error is here : });

Rappasoft\LaravelLivewireTables\DataTableComponent::applySearchFilter
C:\prace\projekty\sasreport\vendor\rappasoft\laravel-livewire-tables\src\Traits\WithFilters.php:336

                   if ($column->hasSearchCallback()) {

                        // Call the callback

                        ($column->getSearchCallback())($subQuery, $search);

                    } elseif (! $hasRelation || $selectedColumn) { // If the column isn't a relation or if it was previously selected

                        $whereColumn = $selectedColumn ?? $column->column();

                        // TODO: Skip Aggregates

                        if (! $hasRelation) {

                            $whereColumn = Schema::hasColumn($query->getModel()->getTable(), $whereColumn) ? $query->getModel()->getTable() . '.' . $whereColumn : $whereColumn;

                        }

                        // We can use a simple where clause

                        $subQuery->orWhere($whereColumn, 'like', '%' . $search . '%');

                    } else {

                        // Parse the column

                        $relationName = ColumnUtilities::parseRelation($column->column());

                        $fieldName = ColumnUtilities::parseField($column->column());

                        // We use whereHas which can work with unselected relations

                        $subQuery->orWhereHas($relationName, function (Builder $hasQuery) use ($fieldName, $search) {

                            $hasQuery->where($fieldName, 'like', '%' . $search . '%');

                        });

                    }

                }

            });

        }

        return $query;

    }

}

Highest error is here: strtolower($column), array_map('strtolower', $this->getColumnListing($table))

::strtolower
C:\prace\projekty\sasreport\vendor\laravel\framework\src\Illuminate\Database\Schema\Builder.php:150

public function hasColumn($table, $column)

    {

        return in_array(

            strtolower($column), array_map('strtolower', $this->getColumnListing($table))

        );

    }
rappasoft commented 2 years ago

The error doesn't seem to be coming from the package itself. Would need the whole stack trace to be sure. You can use Flare's share feature and drop a link here.

rappasoft commented 2 years ago

Yeah, I can't replicate this issue. If you can find an issue feel free to make a PR to fix it but all the demos I have are working.

qwasyx0 commented 2 years ago

I found out where this issue is coming from.

rappasoft/laravel-livewire-tables/src/Traits/WithFilters.php in function public function applySearchFilter($query)

There is since v.1.14 this change

// TODO: Skip Aggregates
 if (! $hasRelation) {
              $whereColumn = Schema::hasColumn($query->getModel()->getTable(), $whereColumn) ? $query->getModel()->getTable() . '.' . $whereColumn : $whereColumn;
 }

The version before had this code:

// TODO: Skip Aggregates
 if (! $hasRelation) {
              $whereColumn = $query->getModel()->getTable() . '.' . $whereColumn;
 }

Schema::hasColumn is using function of same name in vendor/laravel/framework/src/Illuminate/Database/Schema/Builder.php

   public function hasColumn($table, $column)
    {
        return in_array(
            strtolower($column), array_map('strtolower', $this->getColumnListing($table))
        );
    }

So reverting the change, the issue is there no more and on newest version, searching works. What is the reason for this change? Could it be reverted in next update?