Completed
Push — master ( 29e482...c50087 )
by Arthur
07:40
created

UserRepository   A

Complexity

Total Complexity 35

Size/Duplication

Total Lines 250
Duplicated Lines 1.2 %

Coupling/Cohesion

Components 2
Dependencies 7

Importance

Changes 0
Metric Value
wmc 35
lcom 2
cbo 7
dl 3
loc 250
rs 9
c 0
b 0
f 0

16 Methods

Rating   Name   Duplication   Size   Complexity  
A __construct() 0 8 1
A getActive() 0 4 1
A getBillableActive() 0 4 1
A getPaginated() 3 15 3
A getTrustedMissingPhotos() 0 4 1
A getAllAsDropdown() 0 9 2
A getActivePublicList() 0 8 2
A registerMember() 0 21 4
C ensureMembershipActive() 0 32 7
A updateMember() 0 15 4
A memberLeft() 0 10 1
A recordGoCardlessMandateDetails() 0 8 1
A updateUserPaymentMethod() 0 10 2
A recordGoCardlessSubscription() 0 10 2
A recordInductionCompleted() 0 10 2
A getPendingInductionConfirmation() 0 8 1

How to fix   Duplicated Code   

Duplicated Code

Duplicate code is one of the most pungent code smells. A rule that is often used is to re-structure code once it is duplicated in three or more places.

Common duplication problems, and corresponding solutions are:

1
<?php namespace BB\Repo;
2
3
use BB\Entities\User;
4
use Carbon\Carbon;
5
6
class UserRepository extends DBRepository
7
{
8
9
    /**
10
     * @var User
11
     */
12
    protected $model;
13
    /**
14
     * @var AddressRepository
15
     */
16
    private $addressRepository;
17
    /**
18
     * @var ProfileDataRepository
19
     */
20
    private $profileDataRepository;
21
    /**
22
     * @var SubscriptionChargeRepository
23
     */
24
    private $subscriptionChargeRepository;
25
26
    public function __construct(User $model, AddressRepository $addressRepository, ProfileDataRepository $profileDataRepository, SubscriptionChargeRepository $subscriptionChargeRepository)
27
    {
28
        $this->model = $model;
29
        $this->perPage = 150;
30
        $this->addressRepository = $addressRepository;
31
        $this->profileDataRepository = $profileDataRepository;
32
        $this->subscriptionChargeRepository = $subscriptionChargeRepository;
33
    }
34
35
    public function getActive()
36
    {
37
        return $this->model->active()->get();
38
    }
39
40
    public function getBillableActive()
41
    {
42
        return $this->model->active()->notSpecialCase()->get();
43
    }
44
45
    public function getPaginated(array $params)
46
    {
47
        $model = $this->model->with('roles')->with('profile');
48
49
        if ($params['showLeft']) {
50
            $model = $model->where('status', 'left');
51
        } else {
52
            $model = $model->where('status', '!=', 'left');
53
        }
54
55 View Code Duplication
        if ($this->isSortable($params)) {
56
            return $model->orderBy($params['sortBy'], $params['direction'])->simplePaginate($this->perPage);
57
        }
58
        return $model->simplePaginate($this->perPage);
59
    }
60
61
62
    /**
63
     * Return a collection of members for public display
64
     * @param bool $showPrivateMembers Some members don't want to listed on public pages, set to true to show everyone
65
     * @return mixed
66
     */
67
    public function getActivePublicList($showPrivateMembers = false)
68
    {
69
        if ($showPrivateMembers) {
70
            return $this->model->with('profile', 'roles')->active()->where('status', '!=', 'leaving')->orderBy('given_name')->get();
71
        } else {
72
            return $this->model->with('profile', 'roles')->active()->where('status', '!=', 'leaving')->where('profile_private', 0)->orderBy('given_name')->get();
73
        }
74
    }
75
76
    public function getTrustedMissingPhotos()
77
    {
78
        return \DB::table('users')->join('profile_data', 'users.id', '=', 'profile_data.user_id')->where('key_holder', '1')->where('active', '1')->where('profile_data.profile_photo', 0)->get();
79
    }
80
81
    /**
82
     * Get a list of active members suitable for use in a dropdown
83
     * @return array
84
     */
85
    public function getAllAsDropdown()
86
    {
87
        $members = $this->getActive();
88
        $memberDropdown = [];
89
        foreach ($members as $member) {
90
            $memberDropdown[$member->id] = $member->name;
91
        }
92
        return $memberDropdown;
93
    }
94
95
    /**
96
     * @param array   $memberData The new members details
97
     * @param boolean $isAdminCreating Is the user making the change an admin
98
     * @return User
99
     */
100
    public function registerMember(array $memberData, $isAdminCreating)
101
    {
102
        if (empty($memberData['profile_photo_private'])) {
103
            $memberData['profile_photo_private'] = false;
104
        }
105
106
        if (empty($memberData['password'])) {
107
            unset($memberData['password']);
108
        }
109
110
        $memberData['hash'] = str_random(30);
111
112
        $memberData['rules_agreed'] = $memberData['rules_agreed']? Carbon::now(): null;
113
114
        $user = $this->model->create($memberData);
115
        $this->profileDataRepository->createProfile($user->id);
116
117
        $this->addressRepository->saveUserAddress($user->id, $memberData['address'], $isAdminCreating);
118
119
        return $user;
120
    }
121
122
    /**
123
     * The user has setup a payment method of some kind so they are now considered active
124
     * This will kick off the automated member checking processes
125
     *
126
     * @param integer $userId
127
     */
128
    public function ensureMembershipActive($userId)
129
    {
130
        /** @var User $user */
131
        $user = $this->getById($userId);
132
133
        //user needs to have a recent sub charge and one that was paid or is due
134
135
        $user->active = true;
136
        $user->status = 'active';
137
        $user->save();
138
139
        $outstandingCharges = $this->subscriptionChargeRepository->hasOutstandingCharges($userId);
140
141
        //If the user doesn't have any charges currently processing or they dont have an expiry date or are past their expiry data create a charge
142
        if ( ! $outstandingCharges && ( ! $user->subscription_expires || $user->subscription_expires->lt(Carbon::now()))) {
143
            //create a charge
144
145
            $chargeDate = Carbon::now();
146
147
            //If we are passed the end of month cutoff push the charge date forward to their actual charge date
148
            if ((Carbon::now()->day > 28) && $user->payment_day === 1) {
149
                $chargeDate = $chargeDate->day(1)->addMonth();
150
            }
151
152
            if ($user->payment_method == 'gocardless-variable') {
153
                $this->subscriptionChargeRepository->createChargeAndBillDD($userId, $chargeDate, $user->monthly_subscription, 'due', $user->mandate_id);
154
            } else {
155
                // This will create the monthly sub charge but not take any money, that will happen tomorrow during the normal run
156
                $this->subscriptionChargeRepository->createCharge($userId, $chargeDate, $user->monthly_subscription, 'due');
157
            }
158
        }
159
    }
160
161
    /**
162
     * @param integer $userId           The ID of the user to be updated
163
     * @param array   $recordData       The data to be updated
164
     * @param boolean $isAdminUpdating  Is the user making the change an admin
165
     */
166
    public function updateMember($userId, array $recordData, $isAdminUpdating)
167
    {
168
        //If the password field hasn't been filled in unset it so it doesn't get set to a blank password
169
        if (empty($recordData['password'])) {
170
            unset($recordData['password']);
171
        }
172
173
        //Update the main user record
174
        $this->update($userId, $recordData);
175
176
        //Update the user address
177
        if (isset($recordData['address']) && is_array($recordData['address'])) {
178
            $this->addressRepository->updateUserAddress($userId, $recordData['address'], $isAdminUpdating);
179
        }
180
    }
181
182
    /**
183
     * The member has left, disable their account and cancel any out stand sub charge records
184
     * The payment day is also cleared so when they start again the payment is charge happens at restart time
185
     *
186
     * @param $userId
187
     */
188
    public function memberLeft($userId)
189
    {
190
        $user = $this->getById($userId);
191
        $user->active       = false;
192
        $user->status       = 'left';
193
        $user->payment_day  = '';
194
        $user->save();
195
196
        $this->subscriptionChargeRepository->cancelOutstandingCharges($userId);
197
    }
198
199
    public function recordGoCardlessMandateDetails($userId, $subscriptionId)
200
    {
201
        /** @var User $user */
202
        $user = $this->getById($userId);
203
        $user->mandate_id          = $subscriptionId;
204
        $user->gocardless_setup_id = null;
205
        $user->save();
206
    }
207
208
    public function updateUserPaymentMethod($userId, $paymentMethod, $paymentDay = null)
209
    {
210
        /** @var User $user */
211
        $user = $this->getById($userId);
212
        $user->payment_method = $paymentMethod;
213
        if ($paymentDay) {
214
            $user->payment_day = $paymentDay;
215
        }
216
        $user->save();
217
    }
218
219
    public function recordGoCardlessSubscription($userId, $subscriptionId, $paymentDay = null)
220
    {
221
        /** @var User $user */
222
        $user = $this->getById($userId);
223
        if ($paymentDay) {
224
            $user->payment_day = $paymentDay;
225
        }
226
        $user->subscription_id = $subscriptionId;
227
        $user->save();
228
    }
229
230
    /**
231
     * Record the fact that the user has agreed to the member induction and the rules
232
     *
233
     * @param $userId
234
     */
235
    public function recordInductionCompleted($userId)
236
    {
237
        $user = $this->getById($userId);
238
239
        $user->induction_completed = true;
240
241
        $user->rules_agreed = $user->rules_agreed? $user->rules_agreed: Carbon::now();
242
243
        $user->save();
244
    }
245
246
    public function getPendingInductionConfirmation()
247
    {
248
        return $this->model
0 ignored issues
show
Documentation Bug introduced by
The method where does not exist on object<BB\Entities\User>? Since you implemented __call, maybe consider adding a @method annotation.

If you implement __call and you know which methods are available, you can improve IDE auto-completion and static analysis by adding a @method annotation to the class.

This is often the case, when __call is implemented by a parent class and only the child class knows which methods exist:

class ParentClass {
    private $data = array();

    public function __call($method, array $args) {
        if (0 === strpos($method, 'get')) {
            return $this->data[strtolower(substr($method, 3))];
        }

        throw new \LogicException(sprintf('Unsupported method: %s', $method));
    }
}

/**
 * If this class knows which fields exist, you can specify the methods here:
 *
 * @method string getName()
 */
class SomeClass extends ParentClass { }
Loading history...
249
            ->where('status', '!=', 'left')
250
            ->where('induction_completed', true)
251
            ->where('inducted_by', null)
252
            ->get();
253
    }
254
255
}
256