How to create a function with methods in Laravel - php

I need to create a function of this type, I do not know how it is done and I would like to learn
the function adds to the database, and receives some parameters
event($user)->balande(2.00)->points(300);
example https://github.com/spatie/laravel-activitylog
activity('default')
->performedOn($anEloquentModel)
->causedBy($user)
->withProperties(['customProperty' => 'customValue'])
->log('Look, I logged something');

It's actually quite simple : the first function returns an object instance, and subsequent method calls are applied to this instance (they all return $this, allowing you to chain other method calls afterwards). Have a look at https://en.wikipedia.org/wiki/Fluent_interface
<?php
class Thing{
public function doThat(){
// [do something interesting in this object]
return $this;
}
public function doSomethingElse(){
// [do something interesting in this object]
return $this;
}
}
function Something(){
return new Thing();
}
Something()->doThat()->doSomethingElse();

Related

PHP Have Object Return Different Object

In a few different places I call:
$model=NEW MakeCall($form);
I have updated the MakeCall class with several changes that I want to take affect after a given date. I renamed the original class MakeCallOld
How can I leave my calls to:
$model=NEW MakeCall($form);
intact and within MakeCall do this:
class MakeCall
{ ...
public function __construct($form)
{
//Use Legacy MakeCallOld for stuff before 2016-10-01
if ($form['date']<'2016-10-01') {
$object=NEW MakeCallOld($form);
return $object;
}
$this->perform several functions and set variables...
This currently just returns an empty object of class MakeCallOld but it does not appear to run the constructor in MakeCallOld as all properties are empty. I would just like the entire object of MakeCallOld dropped into $model.
What you need is a static factory constructor. This is the way you should be doing it to add initialization logic or switch constructors depending on the argument.
class MakeCall
{
public function __construct($form)
{
$this->form = $form;
}
public function showForm(){
echo $this->form;
}
public static function create($form){
//put logic for picking object or whatever here!
$object = new MakeCall($form);
//Do more initializing if you want here!
return $object;
}
}
$form = "asdasd";
$model= MakeCall::create($form);
$model->showForm();
Constructors don't have a return value, so by saying return $object you are simply ending the control flow there and doing nothing else, never reaching "perform several functions and set variables". Depending on your structure you should consider making MakeCall inherit from MakeCallOld, then you can simply call parent::__construct(); in MakeCall's constructor.

how to call two method with single line in php?

I have seen in Laravel calling multiple method in the single line, example:
DB::get('test')->toJson();
I have a cool class and view method in that class.
$this->call->view('welcome')->anotherMethod();
I would like to call another method also? Where should I make that method?
DB::get() seems to be a method returning an object, where you can call other functions (I think a result object of a database query). If you want to call multiple functions on one object in one line, you have to return $this in your functions, e.g.:
class View {
public static function factory {
// The question is: How useful is this factory function. In fact: useless in
// the current state, but it can be extended in any way
return new self;
}
public function one() {
// do something
return $this;
}
public function two() {
// do something
return $this;
}
}
Then you can do:
$class = new View();
$class->one()->two();
// it's also possible to use the `factory` function
// you should think about, how useful this approach is in your application
$class = View::factory()->one()->two();
That's how you can do it in php, if laravel has some helpers for that, i can't say :)

kill method chain in php

hi i have a method chain in php somewhat like
<?php
auth::('username') -> is_logged() -> doSomething();
//execute something
?>
what i would like to do is if the user is not logged then not invoke the doSomething() function. One way is to unset $this but that would generate an error id there any other way to do it. Also i cant be using die() because it would stop the compiler and prevent codes written afterwards from executing. What is the best way to do it preferably without any warning or error and at the same time making as few changes as possible because of a large number of functions associated with the class.
Return NullObject which will provide empty implementation of doSomething
In PHP you only need to provide the magic __call() method, so any function call will pass.
class NullObject {
public function __call($name, $arguments) {
return $this;
}
}
To use it in your class:
public function is_logged() {
if ($this->user_is_logged()) {
return $this;
} else {
return new NullObject;
}
}

Php Calling the functions of same class one after another

I want to write something like (laravel uses):
View::make('FooBarView')->with('foo', $foo)
->with('bar', $bar);
My knowledge and imagination made me to use new self instances. But I don't think that this is the best idea around and I could not handle it.
Google couldn't help me because of my bad keywords I think. I don't want to make you write code for me for sure but what is the name of this design pattern or whatever?
In laravel's source, with function uses
return $this;
But how to use it after make?
By the way, in this example; with method helps you to set variables for view's render.
To call what the function returns, the function will have to return something that is possible to call.
In this case, you could for example return "this":
class View {
/**
* #returns View
*/
public static function make($foo) {
/* do stuff, return new View instance */
return new View();
}
/**
* #returns View
*/
public function with($foo, $bar){
/* do stuff */
return $this;
}
}
That way, whenever you call with you will get the class instance back, which in turn will be callable:
View::make("foo")->with("foo")->with("bar");
// Will be same as:
$v = View::make("foo");
$v = $v->with("foo");
$v = $v->with("bar");

PHPUnit Test How Many Times A Function Is Called

I'm working on a test in phpunit and I'm running into an issue. I have a public function on my class that I am trying to test. Depending on the parameters passed in to the method, a protected function also in my test class will be called one or two times. I currently have a test in place to check that the return data is correct, but I would also like to make sure the protected method is being called the correct number of times.
I know that a mock object will allow me to count the number of times a function is called, but it will also override the value returned by the protected function. I tried using a mock object with no "will" section, but it would just return null, not the actual value for the protected method.
ExampleClass
public function do_stuff($runTwice){
$results = do_cool_stuff();
if($runTwice){
$results = 2 * do_cool_stuff();
}
return $results;
}
protected function do_cool_stuff()
{
return 2;
}
In my test, I want to check whether do_cool_stuff() was called once or twice, but I still want the return values of both functions to be the same so I can test those as well in my unit test.
tl;dr
I want to count the number of times a protected method in my test object is called (like you can do with a mock object) but I still want all the methods in my test method to return their normal values (not like a mock object).
Alternatively, revert back to rolling your own testable stand-in. The following aint pretty, but you get the idea:
class ExampleClass {
public function do_stuff($runTwice) {
$results = $this->do_cool_stuff();
if ($runTwice) {
$results = 2 * $this->do_cool_stuff();
}
return $results;
}
protected function do_cool_stuff() {
return 2;
}
}
class TestableExampleClass extends ExampleClass {
/** Stores how many times the do_cool_stuff method is called */
protected $callCount;
function __construct() {
$this->callCount = 0;
}
function getCallCount() {
return $this->callCount;
}
/** Increment the call counter, and then use the base class's functionality */
protected function do_cool_stuff() {
$this->callCount++;
return parent::do_cool_stuff();
}
}
class ExampleClassTest extends PHPUnit_Framework_TestCase {
public function test_do_stuff() {
$example = new ExampleClass();
$this->assertEquals(2, $example->do_stuff(false));
$this->assertEquals(4, $example->do_stuff(true));
}
public function test_do_cool_stuff_is_called_correctly() {
// Try it out the first way
$firstExample = new TestableExampleClass();
$this->assertEquals(0, $firstExample->getCallCount());
$firstExample->do_stuff(false);
$this->assertEquals(1, $firstExample->getCallCount());
// Now test the other code path
$secondExample = new TestableExampleClass();
$this->assertEquals(0, $secondExample->getCallCount());
$secondExample->do_stuff(true);
$this->assertEquals(2, $secondExample->getCallCount());
}
}
I wonder though whether counting the number of times a protected method has been called is really a good test. It's coupling your test to the implementation pretty hard. Does it really matter whether it is called twice, or are you more interested in the interactions with other objects? Or maybe this is pointing towards do_cool_stuff needing a refactor into two separate methods:
class ExampleClass {
public function do_stuff($runTwice) {
if ($runTwice) {
return $this->do_cool_stuff_twice();
} else {
return $this->do_cool_stuff_once();
}
}
//...
}
Try setting a global variable prior to utilizing the class.
$IAmDeclaredOutsideOfTheFunction;
then use it to store the count and simply check it after your functions and classes have been called.

Categories