user12160926
user12160926

Reputation:

Define foreach inside a method to avoid repetition

So I have two methods inside my class that are using the same foreach and they're being repeated within both methods .. Is there a best way to define foreach inside its own method? So I'd like to have the foreach called as $this->loop inside the methods, but then have the foreach inside a method called public function loop().

All help would be appreciated.

So I have the two following methods inside my class:

public function check_missing_blobs(): void
    {
        $profiles = Profile::get([
            'meta_query' => [
                'relation' => 'OR',
                [
                    'key' => 'azure_picture',
                    'value' => '',
                    'compare' => '='
                ],
                [
                    'key' => 'azure_picture_big',
                    'value' => '',
                    'compare' => '='
                ],
            ]
        ]);

        if (count($profiles) === 0) {
            return;
        }

        foreach ($profiles as $profile) {
            $profile->load([
                'azure_picture' => Azure::init()->set_blob_sas_url
                ($profile->get_employee_id()),
                'azure_picture_big' => Azure::init()->set_blob_sas_url
                ($profile->get_employee_id(), 'Big/'),
                'azure_picture_expiration' =>
                    $profile->set_azure_picture_expiration
                    (strtotime('+7 days')),
                'azure_picture_big_expiration' =>
                    $profile->set_azure_picture_big_expiration
                    (strtotime('+7 days')),
            ]);
            $profile->save();
        }
    }

AND:

public function check_blob_expiration(string $days = '+2 days'): bool
    {
        $key = 'check_blob_expiration';

        $settings = $this->get_settings($key);

        if ($settings->started <= $settings->finished) {
            $settings->started = time();
        }

        $profiles = Profile::get([
            'post_status' => [
                'publish', 'draft', 'pending', 'private'
            ],
            'posts_per_page' => 250,
            'meta_query' => [
                'relation' => 'OR',
                [
                    'key' => 'azure_picture_expiration',
                    'value' => strtotime($days),
                    'compare' => '<=',
                ],
                [
                    'key' => 'azure_picture_big_expiration',
                    'value' => strtotime($days),
                    'compare' => '<=',
                ],
            ],
            'paged' => $settings->page,
        ]);

        if (count($profiles) === 0) {
            $settings->page = 0;
            $settings->finished = time();
            echo '<pre>No azure blobs expiring within 2 days.</pre>';
            return $this->set_settings($key, $settings);
        }

        foreach ($profiles as $profile) {
            $profile->load([
                'azure_picture' => Azure::init()->set_blob_sas_url
                ($profile->get_employee_id()),
                'azure_picture_big' => Azure::init()->set_blob_sas_url
                ($profile->get_employee_id(), 'Big/'),
                'azure_picture_expiration' =>
                    $profile->set_azure_picture_expiration
                    (strtotime('+7 days')),
                'azure_picture_big_expiration' =>
                    $profile->set_azure_picture_big_expiration
                    (strtotime('+7 days')),
            ]);
            $profile->save();
        }

        if (!empty($profiles)) {
            $settings->page++;
        } else {
            $settings->page = 0;
            $settings->finished = time();
        }

        return $this->set_settings($key, $settings);
    }

Upvotes: 0

Views: 55

Answers (1)

jibsteroos
jibsteroos

Reputation: 1391

You could envisage using a trait.

In short, a trait allows you to: reuse sets of methods freely in several independent classes living in different class hierarchies. (source: the manual).

An example to help better understand the concept:

  1. Define a trait, call it e.g. Iterate, here it has one function loop(array $arr)
  2. Inside the class where you want to use function loop, use: use Iterate
  3. Now, as you can see, we can invoke the function: $this->loop() inside class Test

.

<?php

trait Iterate
{
    public function loop(array $arr)
    {
        foreach ($arr as $key => $value) {
            echo 'key : ' . $key;
            echo '<br />';
            echo 'value : ' . $value;
            echo '<br />';
        }
    }
}

class Test
{
    use Iterate;

    public function __construct($arr)
    {
        $this->loop($arr);
    }
}
$arr = [1, 2, 3];
$test = new Test($arr);

Output:

key : 0
value : 1
key : 1
value : 2
key : 2
value : 3

Upvotes: 1

Related Questions