1

I use PHP (with KirbyCMS) and can create this code:

$results = $site->filterBy('a_key', 'a_value')->filterBy('a_key2', 'a_value2');

This is a chain with two filterBy. It works.

However I need to build a function call like this dynamically. Sometimes it can be two chained function calls, sometimes three or more.

How is that done?

Maybe you can play with this code?

chain is just a random number that can be used to create between 1-5 chains.

for( $i = 0; $i < 10; $i ++ ) {
    $chains = rand(1, 5);
}

Examples of desired result

Example one, just one function call

$results = $site->filterBy('a_key', 'a_value');

Example two, many nested function calls

$results = $site->filterBy('a_key', 'a_value')->filterBy('a_key2', 'a_value2')->filterBy('a_key3', 'a_value3')->filterBy('a_key4', 'a_value4')->filterBy('a_key5', 'a_value5')->filterBy('a_key6', 'a_value6');
Devon Bessemer
  • 34,461
  • 9
  • 69
  • 95
Jens Törnell
  • 23,180
  • 45
  • 124
  • 206

2 Answers2

1
$chains = rand(1, 5)
$results = $site
$suffix = ''
for ( $i = 1; $i <= $chains; $i ++) {
    if ($i != 1) {
        $suffix = $i
    }
    $results = $results->filterBy('a_key' . $suffix, 'a_value' . $suffix)
}

If you are able to pass 'a_key1' and 'a_value1' to the first call to filterBy instead of 'a_key' and 'a_value', you could simplify the code by removing $suffix and the if block and just appending $i.

Lithis
  • 1,327
  • 8
  • 14
1

You don't need to generate the list of chained calls. You can put the arguments of each call in a list then write a new method of the class that gets them from the list and uses them to invoke filterBy() repeatedly.

I assume from your example code that function filterBy() returns $this or another object of the same class as site.

//
// The code that generates the filtering parameters:

// Store the arguments of the filtering here
$params = array();

// Put as many sets of arguments you need
// use whatever method suits you best to produce them
$params[] = array('key1', 'value1');
$params[] = array('key2', 'value2');
$params[] = array('key3', 'value3');


//
// Do the multiple filtering
$site = new Site();
$result = $site->filterByMultiple($params);


//
// The code that does the actual filtering
class Site {
    public function filterByMultiple(array $params) {
        $result = $this;
        foreach ($params as list($key, $value)) {
            $result = $result->filterBy($key, $value);
        }
        return $result;
    }
}

If filterBy() returns $this then you don't need the working variable $result; call $this->filterBy() and return $this; and remove the other occurrences of $result.

axiac
  • 68,258
  • 9
  • 99
  • 134