How to use addClause() outside setup() in Laravel Backpack? - laravel-backpack

Say we have the UserCrudController like so:
public function setup()
{
// ...
// This works:
$this->crud->addClause('active');
// ...
}
The addClause() works fine. Now say we add it outside the setup():
public function posts()
{
// ...
// This DOES NOT work:
$this->crud->addClause('active');
// ...
}
Calling addClause() outside like this works, but if its inside a logic, it does not:
public function setup()
{
// This works:
$this->applyQueries();
}
private function applyQueries()
{
// This works:
$this->crud->addClause('active');
// This DOES NOT work:
if (true)
$this->crud->addClause('active');
}
Recap: I need to call addClause() from another function and inside a logic. How?

If you're creating a custom method, there's no way for Backpack to know what you want to do inside that method. Only what you write inside it will happen, in addition to what's in setup(), which is called in the __constructor().
Depending on your use case (list/create/edit/preview/etc), I recommend you take a look at the logic inside Backpack's CrudController. The methods there contain the logic for the operations above, and do use the addClause(). Copy-paste whatever you need to your posts() method. You'll basically be able to use the query where the clauses have been added by taking advantage of the $this->crud object, so the query would be $this->crud->query.

Related

Non-static method cannot be called statically [duplicate]

Im trying to load my model in my controller and tried this:
return Post::getAll();
got the error Non-static method Post::getAll() should not be called statically, assuming $this from incompatible context
The function in the model looks like this:
public function getAll()
{
return $posts = $this->all()->take(2)->get();
}
What's the correct way to load the model in a controller and then return it's contents?
You defined your method as non-static and you are trying to invoke it as static. That said...
1.if you want to invoke a static method, you should use the :: and define your method as static.
// Defining a static method in a Foo class.
public static function getAll() { /* code */ }
// Invoking that static method
Foo::getAll();
2.otherwise, if you want to invoke an instance method you should instance your class, use ->.
// Defining a non-static method in a Foo class.
public function getAll() { /* code */ }
// Invoking that non-static method.
$foo = new Foo();
$foo->getAll();
Note: In Laravel, almost all Eloquent methods return an instance of your model, allowing you to chain methods as shown below:
$foos = Foo::all()->take(10)->get();
In that code we are statically calling the all method via Facade. After that, all other methods are being called as instance methods.
Why not try adding Scope? Scope is a very good feature of Eloquent.
class User extends Eloquent {
public function scopePopular($query)
{
return $query->where('votes', '>', 100);
}
public function scopeWomen($query)
{
return $query->whereGender('W');
}
}
$users = User::popular()->women()->orderBy('created_at')->get();
Eloquent #scopes in Laravel Docs
TL;DR. You can get around this by expressing your queries as MyModel::query()->find(10); instead of MyModel::find(10);.
To the best of my knowledge, starting PhpStorm 2017.2 code inspection fails for methods such as MyModel::where(), MyModel::find(), etc (check this thread), and this could get quite annoying.
One (elegant) way to get around this is to explicitly call ::query() wherever it makes sense to. This will let you benefit from free auto-completion and a nice formatting/indentating for your queries.
Examples
BAD
Snippet where inspection complains about static method calls
// static call complaint
$myModel = MyModel::find(10);
// another poorly formatted query with code inspection complaints
$myFilteredModels = MyModel::where('is_foo', true)
->where('is_bar', false)
->get();
GOOD
Well formatted code with no complaints
// no complaint
$myModel = MyModel::query()->find(10);
// a nicely formatted and indented query with no complaints
$myFilteredModels = MyModel::query()
->where('is_foo', true)
->where('is_bar', false)
->get();
Just in case this helps someone, I was getting this error because I completely missed the stated fact that the scope prefix must not be used when calling a local scope. So if you defined a local scope in your model like this:
public function scopeRecentFirst($query)
{
return $query->orderBy('updated_at', 'desc');
}
You should call it like:
$CurrentUsers = \App\Models\Users::recentFirst()->get();
Note that the prefix scope is not present in the call.
Solution to the original question
You called a non-static method statically. To make a public function static in the model, would look like this:
public static function {
}
In General:
Post::get()
In this particular instance:
Post::take(2)->get()
One thing to be careful of, when defining relationships and scope, that I had an issue with that caused a 'non-static method should not be called statically' error is when they are named the same, for example:
public function category(){
return $this->belongsTo('App\Category');
}
public function scopeCategory(){
return $query->where('category', 1);
}
When I do the following, I get the non-static error:
Event::category()->get();
The issue, is that Laravel is using my relationship method called category, rather than my category scope (scopeCategory). This can be resolved by renaming the scope or the relationship. I chose to rename the relationship:
public function cat(){
return $this->belongsTo('App\Category', 'category_id');
}
Please observe that I defined the foreign key (category_id) because otherwise Laravel would have looked for cat_id instead, and it wouldn't have found it, as I had defined it as category_id in the database.
You can give like this
public static function getAll()
{
return $posts = $this->all()->take(2)->get();
}
And when you call statically inside your controller function also..
I've literally just arrived at the answer in my case.
I'm creating a system that has implemented a create method, so I was getting this actual error because I was accessing the overridden version not the one from Eloquent.
Hope that help?
Check if you do not have declared the method getAll() in the model. That causes the controller to think that you are calling a non-static method.
For use the syntax like return Post::getAll(); you should have a magic function __callStatic in your class where handle all static calls:
public static function __callStatic($method, $parameters)
{
return (new static)->$method(...$parameters);
}

Flutter & Dart: How to check/know which class has called a function?

I am trying to know which class has called a specific function. I've been looking through the docs for this, but without success. I already know how to get the name of a class, but that is something different of what I'm looking for. I found already something related for java but for dart I haven't. Maybe I'm missing something.
Let's say for example that I have a print function like so:
class A {
void printSomethingAndTellWhereYouDidIt() {
// Here I would also include the class where this function is
// being called. For instance:
print('you called the function at: ...');
//This dot-dot-dot is where maybe should go what I'm looking for.
}
}
class B {
A a = A();
void test() {
a.printSomethingAndTellWhereYouDidIt();
}
}
The output should be something like:
you called the function at: B
Please let me know if there are ways to achieve this. The idea behind is to then use this with a logger, for instance the logging package. Thank you in advance.
You can use StackTrace.current to obtain a stack trace at any time, which is the object that's printed when an exception occurs. This contains the line numbers of the chain of invocations leading up to the call, which should provide the information you need.
class A {
void printSomethingAndTellWhereYouDidIt() {
print(StackTrace.current);
}
}
class B {
A a = A();
void test() {
a.printSomethingAndTellWhereYouDidIt();
}
}
If you are doing this for debugging purposes, you can also set a breakpoint in printSomethingAndTellWhereYouDidIt to check where it was called from.

Call a method only once within XCUITest in Swift 4

My test suite contains some test cases. I have some private functions where I will check elements existence. Consider I have three test cases:
func test_1() {
...
checkListViewElements()
...
}
func test_2() {
...
}
func test_3() {
...
checkListViewElements()
...
}
private func checkListViewElements() {
//Checking existence
}
Since I consider each test case as independent, the private function checkListViewElements() may get repeat within the test cases.
Problem:
When I run the whole test suite, all the three test cases(test_1, test_2 and test_3) will be executed.
The private method checkListViewElements() will be called twice. This will result with the increased amount of test suite completion time.
What I wanted:
I have so many functions like checkListViewElements() within my code. I want them to run only once when I run the whole test suite. (Remember, for each test case, the application terminates and open freshly)
What I tried:
var tagForListViewElementsCheck = "firstTime" //Global variable
private func checkListViewElements() {
if tagForListViewElementsCheck == "firstTime" {
//Checking existence
tagForListViewElementsCheck = "notFirstTime"
}
else {
//Skip
}
}
If I use local variables as tag, it works fine. But here, I have to create each tag for each private method. I really hated that.
I tried with dispatch_once and it seems not supported in Swift 4
Then I tried with static structs by referring this. It also does not seems working.
If there is any other nice approach to do it? Thanks in advance!
You may use function func setUp(). Its call only once per suite. More info at What is the purpose of XCTestCase's setUp method?.

Can I add a method on es6 class after it is defined?

Method
method() {}
function
function func() {}
Above is just to elaborate difference between method and function.
class Student {
constructor(name, age) {
this.name = name;
this.age = age;
}
method1(){}
}
In the above class, after writing the definition.
I want to add a method2 to the class, similar to the way method1 is there.
I can add a function like soo
Student.prototype.func = function(){...}
But I do not have a way to add a method on the same class. and inside function I will not be able to use super as that is just available inside the method.
Is there a way I can add method after the class is defined ?
So that I will be able to use super inside that.
As has already been explained, you can only use super() inside the regular class definition. But, long before we had ES6, we were calling parent method implementations manually. It can be done using the parent's prototype:
class Person {
talk() {
// some implementation here
}
}
class Student extends Person {
constructor(name, age) {
this.name = name;
this.age = age;
}
}
Student.prototype.talk = function(data) {
// now call base method manually
Person.prototype.talk.call(this, data);
// then do our extra work
log(data);
}
Of course, normally you could just declare all your methods within the class declaration so this would not be something you would normally need to do.
Your snippet adding a new property to the prototype is only approach for adding a function later. One main difference in this case is that simple assignment like that will create the property as enumerable by default, whereas class syntax would create is as non-enumerable. You could use
Object.defineProperty(Student.prototype, "func", {
configurable: true,
writable: true,
value: function() {
},
});
to address that at least.
Unfortunately as you've seen, adding things to the prototype afterward does not allow usage of super.foo. There is no way for this to be supported, because the behavior of super is based specifically on the lexical nesting of the method syntax method(){} being inside of the class syntax. Methods added programmatically later on would have no way to know which prototype is the "super" one.

PHPUnit and Zend: Testing a function on a controller?

I have a controller called "SiteController". On it there is a normal indexAction which displays the frontpage. It's fairly easy to test this, but how would I test another function that is NOT an action with parameters. Let's say I have a function called "sendMail($to, $message)". How do I test that?
<?php
class ControllerTest extends Zend_Test_PHPUnit_ControllerTestCase
{
public function testShowCallsServiceFind()
{
$this->dispatch('/index'); // dont care about this...
// what I need is a way to do this:
$res = $controller->sendMail("bla", "bla"); // so that I can test sendMail?
}
}
How can I test sendMail?
You dont actually need to call the dispatch method, you can new up a controller object and call methods directly:
$controller = new \My\Controller();
$actual_result = $controller->sendMail($params);
$this->assertEquals($expected_result, $actual_result);
Be careful though, you'll need to 'mock' your dependencies so you don't actually send a real email when you run your tests! http://phpunit.de/manual/3.0/en/mock-objects.html