2

Edit2: The problem is solved now thanks to @tabacitu. Thanks to everyone who tried to help! Please refer to this github thread for further information while I update the question: https://github.com/Laravel-Backpack/CRUD/issues/2049

Edit: I have tried this on a completely fresh backpack installation using only the User model. Same problem.

Added the following route at the and of routes/backpack/custom.php:

Route::get('test/{id}', 'UserCrudController@index');

This is my URL: https://example.com/admin/test/30

Then added the following code to my UserCrudController.php:

$id = \Route::current()->parameter('id');        

Now again, this doesn't work:

$this->crud->addClause('where','id', "=", $id); //produces empty result, but $id contains 30

But this does work:

$this->crud->addClause('where','id', "=", 30); //here I get my user with id 30.


I have an Article model and am using $this->crud->addClause('where','user_id',backpack_user()->id); to limit the articles shown to those belonging to the currently logged in user.

I now want to further filter my articles by only showing articles that have a certain page_id - in fact, I can do this without any hassle:

$this->crud->addClause('where','page_id', "=", "154");

Now only articles that have a page_id of 154 are shown.

Obviously I want a dynamic variable for page_id, so my url looks like this

http://example.com/admin/articles/154

and I extract the last parameter like this:

$segments = request()->segments();
$page_id = $segments[count($segments)-1]; //get last segment, contains "154"

Now my problem is that for some obscure reason, whenever I try to use

$this->crud->addClause('where','page_id', "=", $page_id);

The collection is empty, even tho dd()'ing $page_id shows it is set and contains "154". I have even tried to cast $page_id to int like this and in fact it becomes an int but still the same problem (empty collection):

$page_id = (int)$segments[count($segments)-1]; //shows 154


Edit: Here are the outputs of dd($this->crud->query->toSql());:

//limit access to user owned models
$this->crud->addClause('where','user_id',backpack_user()->id);    
//produces "select * from `articles` where `user_id` = ?"
dd($this->crud->query->toSql());

//limit entries to those with samge page_id as in URL
$page_id = \Route::current()->parameter('page_id');
$this->crud->addClause('where','page_id',$page_id);       
//produces "select * from `articles` where `user_id` = ? and `page_id` = ?"
dd($this->crud->query->toSql());

Thanks for any help!

Adrenaxus
  • 1,593
  • 2
  • 18
  • 34
  • Could you print the query log and see whats the last query after you added $page_id – ascsoftw Sep 09 '19 at 07:36
  • Thanks for your answer. I updated my question accordingly. Query logs look ok at least I can't find any anomaly there. – Adrenaxus Sep 09 '19 at 07:50
  • What about `dd($this->crud->query->getBindings());` ? – Clément Baconnier Sep 09 '19 at 08:27
  • In the original part you said you use `request->segments` to get the page id, but in the edit part, it becomes `Route->parameter`. So if you still type `/154` in the address bar then.. – shingo Sep 09 '19 at 08:32
  • `dd($this->crud->query->getBindings());` shows the intended result (array containing 2 elements: `0 => my_user_id` and 1 => `my_page_id`. Sry for using `request->segments` first then `Route->parameter` but it shouldn't make a difference as the resulting page_id is always the same. – Adrenaxus Sep 09 '19 at 08:41
  • I feel like the problem is not where we expect to be. Can you confirm that when you do `154`, or `$page_id = 154` or `$page_id = ...->parameter('page_id')` **with any other change and the same user, on the same environment** only `154` or `$page_id = 154` will work? Keeping in mind that `->parameter('page_id')` returns `"154"` – Clément Baconnier Sep 09 '19 at 10:58
  • Are you telling that if you replaced just this `$this->crud->addClause('where','page_id', "=", $page_id);` with this `$this->crud->addClause('where','page_id', "=", "154");` **without changing any other thing**, you get the expected result ?? – Accountant م Sep 09 '19 at 11:23
  • I meant **without any** – Clément Baconnier Sep 09 '19 at 18:03
  • @cbaconnier Thanks for your reply. I also feel like the problem is somewhere else. I can confirm that as soon as I set `$page_id = 154` manually, it works! Yet if I `dd` the content of $page_id when NOT set manually, it shows `154`! – Adrenaxus Sep 10 '19 at 06:53
  • 2
    @Adrenaxus Since you direct set $page_id = 154 and it work. So your dd($page_id) displayed as **154**, but it not actual 154 number. How about the way you define your route ? Your route define could add some special character (blank character) so it make your query do not work. Further more, even depend on your keyboard encode that make your URL display **154**, but no really 154 number. – Vo Kim Nguyen Sep 10 '19 at 09:03
  • Can you try `DB::enableQueryLog(); //your query \Log::debug(DB::getQueryLog()); DB::disableQueryLog();` and let us know the query you are generating? – Prafulla Kumar Sahu Sep 10 '19 at 09:37
  • @Adrenaxus What versions (php, laravel, backpack) are you running? – Bart Sep 10 '19 at 22:00
  • 1
    @Adrenaxus Finally, maybe a silly question, but are you completely sure you are running all these tests against the same database - it looks like there are no records in DB matching your criteria, code seems fine (int,string - both should be automatically converted to int and just work) – Bart Sep 10 '19 at 22:52
  • @PrafullaKumarSahu listening to the query log always produces an empty array, it doesn't produce anything other than an empty array anywhere in my application. – Adrenaxus Sep 11 '19 at 07:12
  • @Bart I have PhP v7.2.22, Laravel 5.8 and backpack 3.5. Also I am sure that all the tests are running against the same DB. In fact, as I said, as soon as I manually set the variable it works so it must be the right DB... – Adrenaxus Sep 11 '19 at 07:14
  • I don't know if this works on laravel backpack. But can't you get the id like this in your controller? `public function index($id)` ? – Clément Baconnier Sep 11 '19 at 09:51
  • You're doing something wrong. Forgetting about a cache, confusing your variables, who knows. Questions from new users claiming that replacing a variable with a scalar fixes all their problems are quite common, and always misguided. There is nothing more basic in a programming language than simple variable assignment, and I can assure you it is not broken. – miken32 Sep 12 '19 at 21:22
  • BTW I attempted to install this software onto a fresh Laravel 5.8 project, but its installer `php artisan backpack:base:install` got hung up in Composer hell. – miken32 Sep 12 '19 at 21:23

2 Answers2

2

Time to swoop in for the bounty! :-) Copy of my answer in this thread.

Your problem is most likely with the AJAX datatables URL. It doesn't get the parameter, so it doesn't apply it.

Basically:

  • the /town_id/x route points to Controller::index()
  • CrudController::index() just loads the view;
  • the view tells DataTables to load the information from the url($crud->route.'/search').'?'.Request::getQueryString() route; which will NOT include your town_id parameter; because it uses $crud->route(), which is specified in your setup(); it does NOT include /town_id/x;

SOLUTION A

One way to get around this:

  • instead of having a route for it, use a GET parameter: example.com/admin/users/?town_id=20
  • you'll be able to get that parameter and apply things to search() from your setup() method:
        if (\Route::getCurrentRoute()->getActionMethod() == 'search' && \Request::has('town_id')) {
            $this->crud->addClause('where', 'select', \Request::get('town_id'));
        }

SOLUTION B

Overwrite the datatables_logic.blade.php file that Backpack provides, and replace $crud->route with Route::getCurrentRoute() or something of that nature - use Laravel's way of getting the current URL, instead of $this->crud. This will make your AJAX calls to the current URL (not the URL you defined for the CRUD with $this->crud->setRoute()).


I would recommend option 1, to be honest.

tabacitu
  • 6,047
  • 1
  • 23
  • 37
  • Not quite. The variable DID contain the right value in index(). It’s just that the search happens in a different method, search(), and by the time it reaches that method the parameter gets stripped. – tabacitu Sep 15 '19 at 05:12
1

I am install demo of backpack and tried it. I am test it in MonsterCrudController and everything was right.

The question mark (?) in dd($this->crud->query->toSql());doesn't matter at all.

enter image description here

But my suggestion:

Try this one first

$this->crud->addClause('where','id', "=", (int)$id);

If it doesn't work for you, be sure to trace your $id variable.

Mahdi Bashirpour
  • 17,147
  • 12
  • 117
  • 144
  • Thank you for your answer. Unfortunately the problem still persists. If I use `$this->crud->addClause('where','page_id', "=", "'7'");` still doesnt work, `$this->crud->addClause('where','page_id', "=", "7");` works, also `$this->crud->addClause('where','page_id', "=", strval(7));` works as well. – Adrenaxus Sep 11 '19 at 07:26
  • Please set manually $page_id and test again. `$page_id = 155`. @Adrenaxus – Mahdi Bashirpour Sep 11 '19 at 08:14
  • I wrote many times in comments and in my original post that if I set `$page_id` manually it always works. – Adrenaxus Sep 11 '19 at 08:41
  • Are you test this `$page_id=154; $this->crud->addClause('where','page_id', "=", $page_id);` @Adrenaxus – Mahdi Bashirpour Sep 11 '19 at 08:52
  • Yes, I tried exactly that and can confirm that it works. I'm beginning to think that for some reason `$this->crud->addClause(` cannot accept a variable... or you need to define a helper function like `backpack_user` in `src/helpers.php` that returns the variable... or need to use `use($variable)` in some closure or something.... – Adrenaxus Sep 11 '19 at 08:58
  • Could you please also check the `$this->crud->addClause('where','page_id', "=", 0+$page_id);` – Constantine Sep 11 '19 at 12:49
  • Let's be ugly as hell : `$this->crud->addClause('where', 'page_id', '=', &$page_id);` – Thierry Leroux Sep 11 '19 at 13:48
  • `$this->crud->addClause('where','page_id', "=", 0+$page_id);` doesnt work, and `$this->crud->addClause('where', 'page_id', '=', &$page_id);` produces "unexpected '&'" error. – Adrenaxus Sep 12 '19 at 09:18
  • Surely your `$page_id variable` is having a problem. @Adrenaxus – Mahdi Bashirpour Sep 12 '19 at 09:21
  • Is it possible for you to share your code? @Adrenaxus – Mahdi Bashirpour Sep 12 '19 at 09:23
  • 1
    Sure, I can share whatever is needed. Please look at my edit, I tried everything with a *fresh* backpack installation with only 3 lines of code added - should be easier to debug that. – Adrenaxus Sep 12 '19 at 09:45
  • @Adrenaxus What you mean saying `0+$page_id` doesnt work? Is the result the same as without `0+`? – Constantine Sep 12 '19 at 09:53
  • I am now creating a project with the same specifications and then testing. @Adrenaxus – Mahdi Bashirpour Sep 12 '19 at 11:24
  • @MahdiBashirpour `query->toSql()` doesn't show actual value bindings. Database driver (mysqlnd) is responsible for query preparation and value binding. Was `addClause('where', 'page_id', "=", $page_id)` succesfull in your environment? – Constantine Sep 12 '19 at 14:02
  • That is succesfull run in my environment. @Constantine – Mahdi Bashirpour Sep 12 '19 at 14:47