Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Defining class constants in facades

I have a couple of libraries defined for my Laravel application which expose constants.

For example, I have a class for calculating holidays and work days, used for counting the number of working days for some reports.

My class definition looks like this:

<?php namespace MyApp\Libraries;

/**
 * The Holiday Calculation Helper Library
 *
 * A helper class to calculate holidays and working days.
 */
class Holidays {

    /**
     * The defined EBS holidays: New Years Day
     */
    const NEW_YEARS_DAY          = "new years day";
    /**
     * The defined EBS holidays: Independence Day
     */
    const INDEPENDENCE_DAY       = "independence day";
    /**
     * The defined EBS holidays: Christmas Day
     */
    const CHRISTMAS_DAY          = "christmas day";

    ...

These are used by (for example) a date method which takes the holiday constant value and a year and returns the date of that holiday in that year. I have a facade and a service provider set up so this library can be used in The Laravel Way™.Everything works perfectly, I have unit tests for everything, and I'm happy with the code.

The question I have is about how to refer to these constants. If I'm using the facade and calling the library from other parts of my code, it looks like this:

$xmas = \Holidays::date(\MyApp\Libraries\Holidays::CHRISTMAS_DAY, "2014");

It works, but I'd prefer to use the facade to do it, like this:

$xmas = \Holidays::date(\Holidays::CHRISTMAS_DAY, "2014");

One solution I thought of is to define the constants in the facade. This works, but then I'm separating the constant values from the library - for obvious reasons, I'd prefer to keep the values with the code that they're associated with.

Then, I hit on another solution: define the constants as above, then reference them in the facade like so:

<?php namespace MyApp\Facades;

use Illuminate\Support\Facades\Facade;

class Holidays extends Facade {

    /**
     * The defined EBS holidays: New Years Day
     */
    const NEW_YEARS_DAY          = \MyApp\Libraries\Holidays::NEW_YEARS_DAY;
    /**
     * The defined EBS holidays: Independence Day
     */
    const INDEPENDENCE_DAY       = \MyApp\Libraries\Holidays::INDEPENDENCE_DAY;
    /**
     * The defined EBS holidays: Christmas Day
     */
    const CHRISTMAS_DAY          = \MyApp\Libraries\Holidays::CHRISTMAS_DAY;

    ...

Now I can refer to the constants through the facade instead of the fully-qualified library class, and I only have to define a value for the constant once (although I do need to add any new constants to both the library and the facade). This works, and it gets me what I want, but it feels a little like a violation of the DRY (Don't Repeat Yourself) principle.

So here's the question. Is this the best way to do this?

like image 280
Kryten Avatar asked Apr 28 '14 15:04

Kryten


1 Answers

You can use use to alias your \MyApp\Libraries\Holidays class, but unfortunately, using Holidays will throw a fatal error, so I'd suggest aliasing it as Holiday which may also save you some confusion in the future.

Add before you declare your class declaration and after you declare your namespace...

use \MyApp\Libraries\Holidays as Holiday;

Use inside your class like so....

$xmas = \Holidays::date(Holiday::CHRISTMAS_DAY, "2014");
like image 156
user1669496 Avatar answered Sep 24 '22 17:09

user1669496