3
\$\begingroup\$
<?php

namespace App\Repositories;

use App\Contracts\{
    CompanyInterface,
    ImageUploaderInterface
};
use App\Models\Company;
use Illuminate\Support\Facades\Auth;

class CompanyRepository implements CompanyInterface
{
    protected $imageUploaderRepository;

    public function __construct(ImageUploaderInterface $imageUploaderRepository)
    {
        $this->imageUploaderRepository = $imageUploaderRepository;
    }

    public function myCompany(): Company
    {
        $companies = Auth::user()->companies;

        if ($companies && $companies->count() > 0) {
            return $companies->first();
        }

        return new Company();
    }

    public function upsert(Company $company, array $validated): Company
    {
        $company->name = $validated['name'];
        $company->address_number = $validated['address_number'];
        $company->address_street = $validated['address_street'];
        $company->address_city = $validated['address_city'];
        $company->address_region = $validated['address_region'];
        $company->address_postcode = $validated['address_postcode'];
        $company->address_country = $validated['address_country'];
        $company->address_geolocation = $validated['address_geolocation'];
        $company->contact_number = $validated['contact_number'];
        $company->contact_email = $validated['contact_email'];
        $company->fax_number = $validated['fax_number'];
        $company->opening_times = json_encode($validated['opening_times']);
        $company->timezone = $validated['timezone'];

        if (array_key_exists('logo', $validated)) {
            $this->imageUploaderRepository->deleteIfExists($company->logo);
            $company->logo = $this->imageUploaderRepository->uploadCompanyLogo($validated['logo']);
        }

        $company->save();

        if ($company->wasRecentlyCreated) {
            $company->user()->attach(Auth::user());
        }

        return $company;
    }
}

This works as expected, however I am not entirely sure if what I have done adheres to S.O.L.I.D principles and infact a good implementation of repository pattern.

Given the contexts:

  1. I have two models (User and Company) and the relationship between the two is many-to-many
  2. The relationship is enabled via a pivot table (user_company)
  3. At the moment, a user can only have one company, later I will be making it possible for a user to own more than one company.
  4. Company's logo can be replaced with a new one.

My issue / what I am unsure of is;

  1. Is it okay that I use Auth::User in this repository? or should the logic of loading user's myCompany be put in UserRepository?
  2. Is it okay for me to use another repository (e.g. imageUploaderRepository) in this repository?
  3. Should controller be the one to orchestrate the logo uploading and not mix the operation in the company repo?
  4. Is it okay that I do the many-to-many linking (via attach) in this repo? or should the controller do it?

P.S. this is how I use the repo in my controller:

public function save(SaveCompanyRequest $request)
{
    $company = $this->companyRepository->myCompany();
    $validated = $request->validated();

    $this->companyRepository->upsert($company, $validated);

    return redirect()
        ->back()
        ->with('status', 'Company details updated.');
}

And here are my interfaces:

And the other two repositories i am using in CompanyInterface:

Lastly, the two related models:

\$\endgroup\$
  • \$\begingroup\$ Are you able to include the implementation for the Company Model class? \$\endgroup\$ – Sᴀᴍ Onᴇᴌᴀ Apr 22 '18 at 2:46
  • \$\begingroup\$ @SamOnela sure, question has been updated. \$\endgroup\$ – Latheesan Apr 22 '18 at 11:47
  • 1
    \$\begingroup\$ Since you are using laravel you could do collect($validated)->map(function($val, $key) use($company){$company->$key = ($key != "opening_times"? $val : json_encode($val));}); \$\endgroup\$ – Luis felipe De jesus Munoz Apr 24 '18 at 14:06
  • \$\begingroup\$ Whit that you avoid all those repetitive lines in the upsert function \$\endgroup\$ – Luis felipe De jesus Munoz Apr 24 '18 at 14:07
  • \$\begingroup\$ Just, forget about repository pattern, look at the code your are returning Eloquent instance of Company, what good is that? You need to return array or some other object but not Eloquent* you defeat the purpose. Whole repository pattern is just big fuss in Laravel community. Good luck! :) \$\endgroup\$ – Kyslik May 9 '18 at 7:54

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Browse other questions tagged or ask your own question.