Skip to content

Instantly share code, notes, and snippets.

@codeperl
Created October 13, 2021 12:10
Show Gist options
  • Save codeperl/40173ffb863c4c6eb5f271d45b570f14 to your computer and use it in GitHub Desktop.
Save codeperl/40173ffb863c4c6eb5f271d45b570f14 to your computer and use it in GitHub Desktop.
php is bad language to a lot of people, right? So, when I need to use php this is how I write it!
<?php
namespace App\Http\Controllers\Web\Front;
use App\Http\Controllers\Controller;
use App\Repositories\AboutUsRepository;
use App\Repositories\BannerRepository;
use App\Repositories\ClientCategoryRepository;
use App\Repositories\ClientRepository;
use App\Repositories\CompanyInfoRepository;
use App\Repositories\ContactRepository;
use App\Repositories\EventRepository;
use App\Repositories\LocationRepository;
use App\Repositories\ManagementRepository;
use App\Repositories\MarketConcentrationRepository;
use App\Repositories\PortfolioCategoryRepository;
use App\Repositories\PortfolioRepository;
use App\Repositories\ProductRepository;
use App\Repositories\ResourceInfoRepository;
use App\Repositories\TestimonialRepository;
/**
* Class IndexController
* @package App\Http\Controllers\Web\Front
*/
class IndexController extends Controller
{
/** @var CompanyInfoRepository */
private $companyInfoRepository;
/** @var ContactRepository */
private $contactRepository;
/** @var LocationRepository */
private $locationRepository;
/** @var BannerRepository */
private $bannerRepository;
/** @var ResourceInfoRepository */
private $resourceInfoRepository;
/** @var MarketConcentrationRepository */
private $marketConcentrationRepository;
/** @var AboutUsRepository */
private $aboutUsRepository;
/** @var ClientCategoryRepository */
private $clientCategoryRepository;
/** @var ClientRepository */
private $clientRepository;
/** @var ProductRepository */
private $productRepository;
/** @var PortfolioCategoryRepository */
private $portfolioCategoryRepository;
/** @var PortfolioRepository */
private $portfolioRepository;
/** @var TestimonialRepository */
private $testimonialRepository;
/** @var EventRepository */
private $eventRepository;
/** @var ManagementRepository */
private $managementRepository;
/**
* IndexController constructor.
* @param CompanyInfoRepository $companyInfoRepository
* @param ContactRepository $contactRepository
* @param LocationRepository $locationRepository
* @param BannerRepository $bannerRepository
* @param ResourceInfoRepository $resourceInfoRepository
* @param MarketConcentrationRepository $marketConcentrationRepository
* @param AboutUsRepository $aboutUsRepository
* @param ClientRepository $clientRepository
* @param ClientCategoryRepository $clientCategoryRepository
* @param ProductRepository $productRepository
* @param PortfolioCategoryRepository $portfolioCategoryRepository
* @param PortfolioRepository $portfolioRepository
* @param TestimonialRepository $testimonialRepository
* @param EventRepository $eventRepository
* @param ManagementRepository $managementRepository
*/
public function __construct(CompanyInfoRepository $companyInfoRepository,
ContactRepository $contactRepository,
LocationRepository $locationRepository,
BannerRepository $bannerRepository,
ResourceInfoRepository $resourceInfoRepository,
MarketConcentrationRepository $marketConcentrationRepository,
AboutUsRepository $aboutUsRepository,
ClientRepository $clientRepository,
ClientCategoryRepository $clientCategoryRepository,
ProductRepository $productRepository,
PortfolioCategoryRepository $portfolioCategoryRepository,
PortfolioRepository $portfolioRepository,
TestimonialRepository $testimonialRepository,
EventRepository $eventRepository,
ManagementRepository $managementRepository)
{
$this->companyInfoRepository = $companyInfoRepository;
$this->contactRepository = $contactRepository;
$this->locationRepository = $locationRepository;
$this->bannerRepository = $bannerRepository;
$this->resourceInfoRepository = $resourceInfoRepository;
$this->marketConcentrationRepository = $marketConcentrationRepository;
$this->aboutUsRepository = $aboutUsRepository;
$this->clientRepository = $clientRepository;
$this->clientCategoryRepository = $clientCategoryRepository;
$this->productRepository = $productRepository;
$this->portfolioCategoryRepository = $portfolioCategoryRepository;
$this->portfolioRepository = $portfolioRepository;
$this->testimonialRepository = $testimonialRepository;
$this->eventRepository = $eventRepository;
$this->managementRepository = $managementRepository;
}
/**
* @return \Illuminate\Contracts\Foundation\Application|\Illuminate\Contracts\View\Factory|\Illuminate\Contracts\View\View
*/
public function index()
{
$companyInfo = $this->companyInfoRepository->first();
$contact = $this->contactRepository->findPrimaryOrFirst();
$location = $this->locationRepository->first();
$banners = $this->bannerRepository->all()->sortBy('order');
$resourceInfo = $this->resourceInfoRepository->first();
$marketConcentrations = $this->marketConcentrationRepository->all()->sortBy('order');
$aboutUs = $this->aboutUsRepository->first();
$clientsCount = $this->clientRepository->count();
$clientCategoriesWithClients = $this->clientCategoryRepository->categoriesWithOrderedClients();
$products = $this->productRepository->all()->sortBy('order');
$portfolioCategories = $this->portfolioCategoryRepository->all()->sortBy('order');
$portfolios = $this->portfolioRepository->all()->sortBy('order');
$testimonials = $this->testimonialRepository->all()->sortBy('order');
$events = $this->eventRepository->findLatestPublishedEvents(3);
$managements = $this->managementRepository->all()->sortBy('order');
return view('web.front.index.index', compact(
'companyInfo', 'contact', 'location', 'banners', 'resourceInfo', 'marketConcentrations', 'aboutUs',
'clientsCount', 'clientCategoriesWithClients', 'products', 'portfolioCategories', 'portfolios',
'testimonials', 'events', 'managements'
));
}
}
@codeperl
Copy link
Author

codeperl commented Oct 13, 2021

@himelnagrana To make it eye-friendly, I can think of only one solution till now and that is to create a Service class called, IndexPageService and pick necessary data from it. But again, It will surely break SRP.

@codeperl
Copy link
Author

codeperl commented Oct 13, 2021

and this is what it looks like without any business value:

namespace App\Http\Controllers\Web\Front;

use App\Http\Controllers\Controller;
use App\Services\Contracts\IndexPageContract;

class IndexController extends Controller
{
    private $indexPageService;

    public function __construct(IndexPageContract $indexPageService)
    {
        $this->indexPageService = $indexPageService;
    }

    public function index()
    {
        return view('web.front.index.index', $this->indexPageService->all());
    }
}

I'll refactor it when needed.

@himelnagrana
Copy link

Thanks for mentioning me and receiving the review professionally and not personally. I really appreciate that.

First, as I mentioned earlier, without much context it is really hard to suggest/discuss a possible solution. But still, the last code snippet you shared is much much readable and debug-friendly. And if it was up to me, I wouldn't mind distributing the service class design also. That means I would have created wrapper service classes for each repository which would expose certain data (that is only relevant). Then accumulate all of them in IndexService class. That would not break SRP.

It might sound a bit elaborate and meaningless work -- but based on the size / usage or the data it would have been a good choice.
And of course, this is a personal opinion.

Secondly, I can't comment about HMVC without more context.

Thirdly, using client frameworks like vue/react would ease this problem actually. From the code, I am guessing and you shared too that there are lots of components/widgets that are interacted by users. What you are basically doing sending a request from browser to backend.

Yes true, there will be lots of HTTP calls. But that also can be minimized. And about reloading page - can very well be replaced with reloading segments/components/widgets of page. And it can be handled by client side libraries. You can check about web applications where the initial pages loads first and data in different sections loads asynchronously.

============

Having said all of this ---- PLEASE consider three things:

  1. consider all of this as my personal opinion
  2. without really knowing the application requirement and context, it is not very wise to comment about things like architecture and/or technology
  3. Whole point of my commenting was you seemed like asking for opinion and I thought if I can help you with some idea -- so that you can read/explore some out of the box idea to solve your problems.

Good luck with that. 🙏🏼

@codeperl
Copy link
Author

codeperl commented Oct 13, 2021

@himelnagrana Thank you very much for your valuable time and input. Surely your input will help me to think about and yes, without knowing the specific requirement it's tough to suggest any specific solution. But as there are multiple ways of solving the same thing, I have to figure it out for this context.

Can't thank you much and that was a very good cross-check for me that can't be done without you guys. Appreciated!

Wishing you a very good day!

@codeperl
Copy link
Author

codeperl commented Oct 14, 2021

PHP is a good thing for people who are trying to learn programming languages. And this is an excellent example of bad code.

@shifatbuet Aah! yeah! It's me and not php.

You may suggest some code re-factoring in this situation. I want to hear from you that where it can be improved. You can forget about the context even.

@codeperl
Copy link
Author

codeperl commented Oct 15, 2021

@shifatbuet , So this is the 2nd part of "php is bad" and for "Beginners only". https://gist.github.com/codeperl/94ebdcb6b86d003e64da43fec31179a9

How did you do it in Java? Annotations? Do you want to check that version? I will suggest you to check Doctrine annotation class and you can do more just by extending that. It is there for at least last 7-8 years!

  1. I see java code in procedural way! Forcing to write classes doesn't make someone "expert", "object oriented design" and that is how java is also forgiving and beginner friendly and that's okay.

    Comparing to java, php is more beginner friendly and forgiving but that does not mean it's a "Beginner only" language.

  2. Even if someone is trying to learn programming with concept, best is to go for c and c++! Not java! If someone want to inspire himself for programming, python is very good choice, not php!

  3. Once people used to develop "simple informative websites" with java or microsoft technology. php makes that easy! Most of the people hates because of that. They lost a lot of extra bucks and php was good enough for those "simple informative websites" they have no more chance to argue!

  4. The best thing php core team did is, taking the criticism positively and constantly tries to improve that.

  5. Scaling is a different issue which is not completely dependent on language.

  6. You can't do something that doesn't mean you need to hate it. :)

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment