All Projects → aimeos → macro

aimeos / macro

Licence: MIT License
Customize code using closures

Programming Languages

PHP
23972 projects - #3 most used programming language
SCSS
7915 projects
HTML
75241 projects
javascript
184084 projects - #8 most used programming language

Projects that are alternatives of or similar to macro

Ngx Dynamic Form Builder
FormBuilder + class-transformer + class-validator = dynamic form group builder for Angular10+
Stars: ✭ 93 (-31.11%)
Mutual labels:  dynamic, class
Laravel Attributes
Rinvex Attributable is a robust, intelligent, and integrated Entity-Attribute-Value model (EAV) implementation for Laravel Eloquent, with powerful underlying for managing entity attributes implicitly as relations with ease. It utilizes the power of Laravel Eloquent, with smooth and seamless integration.
Stars: ✭ 304 (+125.19%)
Mutual labels:  custom, dynamic
lets-hotfix
Dynamic class reloading for java。Java代码热更新,支持本地、远程
Stars: ✭ 124 (-8.15%)
Mutual labels:  dynamic, class
dynamic-form-json
dynamic-form-json is a tiny library to generate a Form in React automatically based on certain array of object that passed as a props
Stars: ✭ 16 (-88.15%)
Mutual labels:  dynamic
HALO-SCRIPT-PROJECTS
✅ Halo PC|CE - Add-ons for Phasor V2+ and SAPP 🇳🇿
Stars: ✭ 25 (-81.48%)
Mutual labels:  custom
BurgerCustomArmor
Create Custom Armor Sets with several abilities!
Stars: ✭ 25 (-81.48%)
Mutual labels:  custom
PHP-Light-SQL-Parser
This class can parse SQL to get query type, tables, field values, etc.. It takes an string with a SQL statements and parses it to extract its different components. Currently the class can extract the SQL query method, the names of the tables involved in the query and the field values that are passed as parameters. This parser is pretty light re…
Stars: ✭ 23 (-82.96%)
Mutual labels:  class
cocoapods-user-defined-build-types
⚒ A cocoapods plugin that can selectively set build type per pod (static library, dynamic framework, etc.)
Stars: ✭ 91 (-32.59%)
Mutual labels:  dynamic
bom-radar-card
A rain radar card using the new tiled images from the Australian BOM
Stars: ✭ 52 (-61.48%)
Mutual labels:  custom
guilyx
Dynamic Profile with github statistics, coding info (time and languages) with WakaTime and music status with the spotify API, leave a ⭐ if you like it
Stars: ✭ 175 (+29.63%)
Mutual labels:  dynamic
CoolSlidingMenu
A powerful menu that you can customize it。
Stars: ✭ 25 (-81.48%)
Mutual labels:  custom
instrumentation
Assorted pintools
Stars: ✭ 24 (-82.22%)
Mutual labels:  dynamic
gatsby-plugin-dynamic-routes
Creating dynamic routes based on your environment and/or renaming existing routes
Stars: ✭ 14 (-89.63%)
Mutual labels:  dynamic
simplevk
SimpleVK это PHP библиотека для быстрой разработки ботов для VK | vk api php class bot sdk library client framework longpoll callback streaming auth
Stars: ✭ 84 (-37.78%)
Mutual labels:  class
angular-expression-parser
This library helps in achieving AngularJs equivalents of $parse, $eval and $watch in Angular.
Stars: ✭ 17 (-87.41%)
Mutual labels:  dynamic
QuadrotorFly
This is a dynamic simulation for quadrotor UAV
Stars: ✭ 61 (-54.81%)
Mutual labels:  dynamic
BashClass
BashClass is an Object Oriented Programming language that compiles to BASH 4.4
Stars: ✭ 40 (-70.37%)
Mutual labels:  class
staticfusion
StaticFusion
Stars: ✭ 107 (-20.74%)
Mutual labels:  dynamic
toxic-decorators
Library of Javascript decorators
Stars: ✭ 26 (-80.74%)
Mutual labels:  class
Functions
Create your own commands with ease! For PocketMine, a Minecraft PE server software
Stars: ✭ 17 (-87.41%)
Mutual labels:  custom

PHP Macro

The PHP Macro package offers closure (anonymous function) based setter dependency injection by providing a trait which can be included into any class.

composer req aimeos/macro

This package is for application, framework and library developers who want to allow customizing the behavior of their code by their users.

Why macros

In applications, frameworks or libraries which are build for customization it’s necessary to allow overwriting existing functionality to be able customize its behavior. This is where macros are very handy because they can add custom code using closures.

With the PHP Macro package, you can also allow users to overwrite methods in base classes without forcing your users to extend these classes. The PHP Macro package uses NO reflection or other hacks, just pure PHP methods.

There are some pros and cons when compared to class based depencency injection:

Pro:

  • Less code to write and much easier to implement for simple stuff
  • Custom closures can be inherited and overwritten like class methods

Con:

  • Limited static code analysis possibilities
  • Anonymous function can not be forced to implement an interface

Thus, it's not a replacement for class based depencency injection but a lightweight addition for small extension points where full-blown dependency injection using classes implementing interfaces are too much work.

Allow customization

The result of existing methods can be modified if the original method checks for an existing macro and use that instead its own implementation:

// original code

class Order
{
    use Aimeos\Macro\Macroable;

    private $id = '123';

    public function getOrderNumber()
    {
        $fcn = static::macro( 'orderNumber' );
        return $fcn ? $fcn( $this->id ) : $this->id;
    }
};

Now, you can add your custom orderNumber macro that will be used instead:

// user code

Order::macro( 'orderNumber', function( string $id ) {
   return date( 'Y' ) . '-' . $id;
} );

(new Order)->getOrderNumber(); // now returns '2020-123'

Thus, you can generate own output or pass a different result to subseqent methods within the application.

Access class properties

When macros are called in an object context, they can also access class properties:

// original code

class A
{
    use Aimeos\Macro\Macroable;
    private $name = 'A';
};

Here, the private property $name is available in the macro:

// user code

A::macro( 'concat', function( array $values ) {
   return $this->name . ':' . implode( '-', $values );
} );

(new A)->concat( ['1', '2', '3'] ); // returns 'A:1-2-3'

The macro can use the property as input for creating the returned value.

Use inherited macros

The PHP macro package also allows to inherit macros from parent classes. Then, they can access class properties of the child class just like regular class methods:

// original code

class A
{
    use Aimeos\Macro\Macroable;
    private $name = 'A';
};

class B extends A
{
    private $name = 'B';
};

Macros added to the parent class will be available in child classes too:

// user code

A::macro( 'concat', function( array $values ) {
   return $this->name . ':' . implode( '-', $values );
} );

(new B)->concat( ['1', '2', '3'] ); // returns 'B:1-2-3'

Class B extends from class A but provides a different $name property. The macro inherited from class A will now use the property of class B.

Overwrite inherited macros

It's also possible to overwrite macros inherited from parent classes as it's possible with regular class methods:

// original code

class A
{
    use Aimeos\Macro\Macroable;

    public function do() {
        return static::macro( 'concat' )( [1, 2, 3] );
    }
};

class B extends A {};

class C extends A {};

Now you can add macros to the parent class and one of the child classes:

// user code

A::macro( 'concat', function( array $values ) {
   return implode( ',', $values );
} );

C::macro( 'concat', function( array $values ) {
   return implode( '-', $values );
} );

(new B)->do(); // returns '1,2,3'

(new C)->do(); // returns '1-2-3'

This enables you to add special handling for single classes even if all other classes still use the macro added to class A.

Overwrite protected methods

Base classes often offer a set of methods that are used by the child classes. In PHP, replacing the methods of a base class is impossible and thus, you have to overwrite each child class with your own implementation.

To avoid that, the original method can use the call() method instead of calling the method of the parent class directly:

// original code

class A
{
    use Aimeos\Macro\Macroable;

    protected function getName( $prefix )
    {
        return $prefix . 'A';
    }
};

class B extends A
{
    public function do()
    {
        return $this->call( 'getName', 'B-' );
    }
};

This will check if there's a macro getName available and will call that instead of the getName() method:

// user code

(new B)->do(); // returns 'B-A'

A::macro( 'getName', function( $prefix ) {
   return $this->getName( $prefix ) . '-123';
} );

(new B)->do(); // returns 'B-A-123'

The original getName() method can still be used in the macro.

Reset macros

Sometimes, it may be necessary to remove macros from objects, especially when running automated tests. You can unset a macro by using:

class A
{
    use Aimeos\Macro\Macroable;
};

// add macro
A::macro( 'test', function() {
   return 'test';
} );

// remove macro
A::unmacro( 'test' );
Note that the project description data, including the texts, logos, images, and/or trademarks, for each open source project belongs to its rightful owner. If you wish to add or remove any projects, please contact us at [email protected].