MOON
Server: Apache
System: Linux server1.studioinfinity.com.br 2.6.32-954.3.5.lve1.4.90.el6.x86_64 #1 SMP Tue Feb 21 12:26:30 UTC 2023 x86_64
User: artinside (517)
PHP: 7.4.33
Disabled: exec,passthru,shell_exec,system
Upload Files
File: //usr/local/lib64/perl5/Cpanel/Class/Meta/Method/Wrapped.pm
package Cpanel::Class::Meta::Method::Wrapped;

use strict;
use warnings;

use Carp 'confess';
use Scalar::Util 'reftype', 'blessed';

use base 'Cpanel::Class::Meta::Method';

our $VERSION = '1.0.5';

my $_build_wrapped_method = sub {
    my $modifier_table = shift;
    my ( $before, $after, $around ) = ( $modifier_table->{'before'}, $modifier_table->{'after'}, $modifier_table->{'around'}, );
    if ( @$before && @$after ) {
        $modifier_table->{'cache'} = sub {
            $_->(@_) for @{$before};
            my @rval;
            (
                ( defined wantarray )
                ? (
                      (wantarray)
                    ? ( @rval = $around->{'cache'}->(@_) )
                    : ( $rval[0] = $around->{'cache'}->(@_) )
                  )
                : $around->{'cache'}->(@_)
            );
            $_->(@_) for @{$after};
            return unless defined wantarray;
            return wantarray ? @rval : $rval[0];
          }
    }
    elsif ( @$before && !@$after ) {
        $modifier_table->{'cache'} = sub {
            $_->(@_) for @{$before};
            return $around->{'cache'}->(@_);
          }
    }
    elsif ( @$after && !@$before ) {
        $modifier_table->{'cache'} = sub {
            my @rval;
            (
                ( defined wantarray )
                ? (
                      (wantarray)
                    ? ( @rval = $around->{'cache'}->(@_) )
                    : ( $rval[0] = $around->{'cache'}->(@_) )
                  )
                : $around->{'cache'}->(@_)
            );
            $_->(@_) for @{$after};
            return unless defined wantarray;
            return wantarray ? @rval : $rval[0];
          }
    }
    else {
        $modifier_table->{'cache'} = $around->{'cache'};
    }
};

sub wrap {
    my $class = shift;
    my $code  = shift;
    ( blessed($code) && $code->isa('Cpanel::Class::Meta::Method') )
      || confess "Can only wrap blessed CODE";
    my $modifier_table = {
        cache  => undef,
        orig   => $code,
        before => [],
        after  => [],
        around => {
            cache   => $code->body,
            methods => [],
        },
    };
    $_build_wrapped_method->($modifier_table);
    my $method = $class->SUPER::wrap( sub { $modifier_table->{'cache'}->(@_) } );
    $method->{'%!modifier_table'} = $modifier_table;
    return $method;
}

sub get_original_method {
    my $code = shift;
    $code->{'%!modifier_table'}->{'orig'};
}

sub add_before_modifier {
    my $code     = shift;
    my $modifier = shift;
    unshift @{ $code->{'%!modifier_table'}->{'before'} } => $modifier;
    $_build_wrapped_method->( $code->{'%!modifier_table'} );
}

sub add_after_modifier {
    my $code     = shift;
    my $modifier = shift;
    push @{ $code->{'%!modifier_table'}->{'after'} } => $modifier;
    $_build_wrapped_method->( $code->{'%!modifier_table'} );
}

{
    my $compile_around_method = sub {
        {
            my $f1 = pop;
            return $f1 unless @_;
            my $f2 = pop;
            push @_, sub { $f2->( $f1, @_ ) };
            redo;
        }
    };

    sub add_around_modifier {
        my $code     = shift;
        my $modifier = shift;
        unshift @{ $code->{'%!modifier_table'}->{'around'}->{'methods'} } => $modifier;
        $code->{'%!modifier_table'}->{'around'}->{'cache'} = $compile_around_method->( @{ $code->{'%!modifier_table'}->{'around'}->{'methods'} }, $code->{'%!modifier_table'}->{'orig'}->body );
        $_build_wrapped_method->( $code->{'%!modifier_table'} );
    }
}

1;