GDPR-IAB-TCFv2

 view release on metacpan or  search on metacpan

README.pod  view on Meta::CPAN

or

    use GDPR::IAB::TCFv2;

    my $consent = GDPR::IAB::TCFv2->Parse(
        'CLcVDxRMWfGmWAVAHCENAXCkAKDAADnAABRgA5mdfCKZuYJez-NQm0TBMYA4oCAAGQYIAAAAAAEAIAEgAA.argAC0gAAAAAAAAAAAA',
        json => {
            verbose        => 0,
            compact        => 1,
            use_epoch      => 0,
            boolean_values => [ 0, 1 ],
            date_format    => '%Y%m%d',    # yyymmdd
        },
        strict => 1,
        prefetch => 284,
    );

Parse may receive an optional hash with the following parameters:

=over

README.pod  view on Meta::CPAN

C<purpose/consents>, C<purpose/legitimate_interests>, C<vendor/consents> and C<vendor/legitimate_interests>. See L</TO_JSON> for more details.

=item *

C<use_epoch> changes the json encode. By default we format the C<created> and C<last_updated> are converted to string using 
L<ISO_8601|https://en.wikipedia.org/wiki/ISO_8601>. With C<use_epoch> we will return the unix epoch in seconds.
See L</TO_JSON> for more details.

=item *

C<boolean_values> if present, expects an arrayref if two elements: the C<false> and the C<true> values to be used in json encoding.
If omit, we will try to use C<JSON::false> and C<JSON::true> if the package L<JSON> is available, else we will fallback to C<0> and C<1>.

=item *

C<date_format> if present accepts two kinds of value: an C<string> (to be used on C<POSIX::strftime>) or a code reference to a subroutine that
will be called with two arguments: epoch in seconds and nanoseconds. If omitted the format L<ISO_8601|https://en.wikipedia.org/wiki/ISO_8601> will be used
except if the option C<use_epoch> is true.

=back

lib/GDPR/IAB/TCFv2.pm  view on Meta::CPAN

    my $segments = _decode_tc_string_segments($tc_string);

    my $strict = !!$opts{strict};

    my %options = (
        json   => $opts{json} || {},
        strict => $strict,
    );

    $options{json}->{date_format}    ||= DATE_FORMAT_ISO_8601;
    $options{json}->{boolean_values} ||= [ _json_false(), _json_true() ];

    if ( exists $opts{prefetch} ) {
        my $prefetch = $opts{prefetch};

        $prefetch = [$prefetch] if ref($prefetch) ne ref( [] );

        $options{prefetch} = $prefetch;
    }

    my $self = {

lib/GDPR/IAB/TCFv2.pm  view on Meta::CPAN

    }

    my $verbose = !!$self->{options}->{json}->{verbose};

    return { map { @{$_} } grep { $verbose || $_->[1] } @data };
}

sub TO_JSON {
    my $self = shift;

    my ( $false, $true ) = @{ $self->{options}->{json}->{boolean_values} };

    my $created      = $self->_format_date( $self->created );
    my $last_updated = $self->_format_date( $self->last_updated );

    return {
        tc_string               => $self->tc_string,
        version                 => $self->version,
        created                 => $created,
        last_updated            => $last_updated,
        cmp_id                  => $self->cmp_id,

lib/GDPR/IAB/TCFv2.pm  view on Meta::CPAN

or

    use GDPR::IAB::TCFv2;

    my $consent = GDPR::IAB::TCFv2->Parse(
        'CLcVDxRMWfGmWAVAHCENAXCkAKDAADnAABRgA5mdfCKZuYJez-NQm0TBMYA4oCAAGQYIAAAAAAEAIAEgAA.argAC0gAAAAAAAAAAAA',
        json => {
            verbose        => 0,
            compact        => 1,
            use_epoch      => 0,
            boolean_values => [ 0, 1 ],
            date_format    => '%Y%m%d',    # yyymmdd
        },
        strict => 1,
        prefetch => 284,
    );

Parse may receive an optional hash with the following parameters:

=over

lib/GDPR/IAB/TCFv2.pm  view on Meta::CPAN

C<purpose/consents>, C<purpose/legitimate_interests>, C<vendor/consents> and C<vendor/legitimate_interests>. See L</TO_JSON> for more details.

=item *

C<use_epoch> changes the json encode. By default we format the C<created> and C<last_updated> are converted to string using 
L<ISO_8601|https://en.wikipedia.org/wiki/ISO_8601>. With C<use_epoch> we will return the unix epoch in seconds.
See L</TO_JSON> for more details.

=item *

C<boolean_values> if present, expects an arrayref if two elements: the C<false> and the C<true> values to be used in json encoding.
If omit, we will try to use C<JSON::false> and C<JSON::true> if the package L<JSON> is available, else we will fallback to C<0> and C<1>.

=item *

C<date_format> if present accepts two kinds of value: an C<string> (to be used on C<POSIX::strftime>) or a code reference to a subroutine that
will be called with two arguments: epoch in seconds and nanoseconds. If omitted the format L<ISO_8601|https://en.wikipedia.org/wiki/ISO_8601> will be used
except if the option C<use_epoch> is true.

=back

lib/GDPR/IAB/TCFv2/BitField.pm  view on Meta::CPAN


sub TO_JSON {
    my $self = shift;

    my @data = split //, $self->{data};

    if ( !!$self->{options}->{json}->{compact} ) {
        return [ grep { $data[ $_ - 1 ] } 1 .. $self->{max_id} ];
    }

    my ( $false, $true ) = @{ $self->{options}->{json}->{boolean_values} };

    if ( !!$self->{options}->{json}->{verbose} ) {
        return { map { $_ => $data[ $_ - 1 ] ? $true : $false }
              1 .. $self->{max_id} };
    }

    return {
        map  { $_ => $true }
        grep { $data[ $_ - 1 ] } 1 .. $self->{max_id}
    };

lib/GDPR/IAB/TCFv2/PublisherTC.pm  view on Meta::CPAN

                \%custom_purpose_legitimate_interests,
                $self->{num_custom_purposes}
            ),
        },
    };
}

sub _format_json_subsection {
    my ( $self, $data, $max ) = @_;

    my ( $false, $true ) = @{ $self->{options}->{json}->{boolean_values} };

    if ( !!$self->{options}->{json}->{compact} ) {
        return [
            grep { $data->{$_} } 1 .. $max,
        ];
    }

    my $verbose = !!$self->{options}->{json}->{verbose};

    return $data if $verbose;

lib/GDPR/IAB/TCFv2/RangeSection.pm  view on Meta::CPAN

    }

    return \@vendors;
}

sub TO_JSON {
    my $self = shift;

    return $self->all if !!$self->{options}->{json}->{compact};

    my ( $false, $true ) = @{ $self->{options}->{json}->{boolean_values} };

    my %map;
    if ( !!$self->{options}->{json}->{verbose} ) {
        %map = map { $_ => $false } 1 .. $self->{max_id};
    }

    foreach my $range ( @{ $self->{ranges} } ) {
        %map = ( %map, map { $_ => $true } $range->[0] .. $range->[1] );
    }

t/02-json-bitfield.t  view on Meta::CPAN

      "should convert data to json using compact flag and 0/1 as booleans" =>
      sub {
        subtest "should convert data to json using yyyymmdd as date format" =>
          sub {
            my $consent = GDPR::IAB::TCFv2->Parse(
                'CLcVDxRMWfGmWAVAHCENAXCkAKDAADnAABRgA5mdfCKZuYJez-NQm0TBMYA4oCAAGQYIAAAAAAEAIAEgAA',
                json => {
                    verbose        => 0,
                    compact        => 1,
                    use_epoch      => 0,
                    boolean_values => [ 0, 1 ],
                    date_format    => '%Y%m%d',    # yyymmdd
                },
            );


            my $got      = $consent->TO_JSON();
            my $expected = _fixture_bitfield_compact(
                created      => 20081207,
                last_updated => 20120110,
            );

t/02-json-bitfield.t  view on Meta::CPAN

            done_testing;
          };

        subtest "should convert data to json using epoch date format" => sub {
            my $consent = GDPR::IAB::TCFv2->Parse(
                'CLcVDxRMWfGmWAVAHCENAXCkAKDAADnAABRgA5mdfCKZuYJez-NQm0TBMYA4oCAAGQYIAAAAAAEAIAEgAA',
                json => {
                    verbose        => 0,
                    compact        => 1,
                    use_epoch      => 1,
                    boolean_values => [ 0, 1 ],
                },
            );


            my $got      = $consent->TO_JSON();
            my $expected = _fixture_bitfield_compact(
                created      => 1228644257,
                last_updated => 1326215413,
            );

t/02-json-bitfield.t  view on Meta::CPAN

      "should convert data to json using default (non-compact) and 0/1 as booleans"
      => sub {

        subtest "default non verbose, date as iso 8601" => sub {
            my $consent = GDPR::IAB::TCFv2->Parse(
                'CLcVDxRMWfGmWAVAHCENAXCkAKDAADnAABRgA5mdfCKZuYJez-NQm0TBMYA4oCAAGQYIAAAAAAEAIAEgAA',
                json => {
                    verbose        => 0,
                    compact        => 0,
                    use_epoch      => 0,
                    boolean_values => [ 0, 1 ],
                },
            );

            ok $consent->vendor_consent(27);

            my $got      = $consent->TO_JSON();
            my $expected = _fixture_bitfield_default();
            is_deeply $got, $expected, "must return the json hashref";

            done_testing;
        };

        subtest "default verbose, date as iso 8601" => sub {
            my $consent = GDPR::IAB::TCFv2->Parse(
                'CLcVDxRMWfGmWAVAHCENAXCkAKDAADnAABRgA5mdfCKZuYJez-NQm0TBMYA4oCAAGQYIAAAAAAEAIAEgAA',
                json => {
                    verbose        => 1,
                    compact        => 0,
                    use_epoch      => 0,
                    boolean_values => [ 0, 1 ],
                },
            );

            ok $consent->vendor_consent(27);

            my $got      = $consent->TO_JSON();
            my $expected = _fixture_bitfield_verbose();
            is_deeply $got, $expected, "must return the json hashref";

            done_testing;

t/02-json-bitfield.t  view on Meta::CPAN

      };

    subtest "publisher section" => sub {
        subtest "publisher section without publisher_tc" => sub {
            my $consent = GDPR::IAB::TCFv2->Parse(
                'COwAdDhOwAdDhN4ABAENAPCgAAQAAv___wAAAFP_AAp_4AI6ACACAA',
                json => {
                    verbose        => 0,
                    compact        => 1,
                    use_epoch      => 0,
                    boolean_values => [ 0, 1 ],
                },
            );

            my $got = $consent->TO_JSON;
            my $expected =
              { "publisher" => { "restrictions" => { "7" => { "32" => 1 } } }
              };

            is_deeply $got->{publisher}, $expected->{publisher},
              "must return the same publisher restriction section";

t/02-json-bitfield.t  view on Meta::CPAN

            done_testing;
        };
        subtest "publisher section with publisher_tc" => sub {
            subtest "without custom purposes" => sub {
                my $consent = GDPR::IAB::TCFv2->Parse(
                    'COwAdDhOwAdDhN4ABAENAPCgAAQAAv___wAAAFP_AAp_4AI6ACACAA.argAC0gAAAAAAAAAAAA',
                    json => {
                        verbose        => 0,
                        compact        => 1,
                        use_epoch      => 0,
                        boolean_values => [ 0, 1 ],
                    },
                );

                my $got      = $consent->TO_JSON;
                my $expected = {
                    "publisher" => {
                        "consents"             => [ 2, 4, 6, 8, 9, 10 ],
                        "legitimate_interests" => [ 2, 4, 5, 7, 10 ],
                        "custom_purposes"      => {
                            "consents"             => [],

t/02-json-bitfield.t  view on Meta::CPAN

                done_testing;
            };

            subtest "with custom purposes" => sub {
                my $consent = GDPR::IAB::TCFv2->Parse(
                    'COwAdDhOwAdDhN4ABAENAPCgAAQAAv___wAAAFP_AAp_4AI6ACACAA.YAAAAAAAAXA',
                    json => {
                        verbose        => 0,
                        compact        => 1,
                        use_epoch      => 0,
                        boolean_values => [ 0, 1 ],
                    },
                );

                my $got      = $consent->TO_JSON;
                my $expected = {
                    "publisher" => {
                        "consents"             => [],
                        "legitimate_interests" => [],
                        "custom_purposes"      => {
                            "consents"             => [ 1, 2 ],

t/02-json-bitfield.t  view on Meta::CPAN

        done_testing;
    };

    subtest "TO_JSON method should return the same hashref " => sub {
        my $consent = GDPR::IAB::TCFv2->Parse(
            'CLcVDxRMWfGmWAVAHCENAXCkAKDAADnAABRgA5mdfCKZuYJez-NQm0TBMYA4oCAAGQYIAAAAAAEAIAEgAA',
            json => {
                verbose        => 0,
                compact        => 1,
                use_epoch      => 0,
                boolean_values => [ 0, 1 ],
            },
        );


        my $got1 = $consent->TO_JSON();
        my $got2 = $consent->TO_JSON();

        is_deeply $got1, $got2, "must return the same hashref";

        done_testing;

t/03-json-range.t  view on Meta::CPAN

      "should convert data to json using compact flag and 0/1 as booleans" =>
      sub {
        subtest "should convert data to json using yyyymmdd as date format" =>
          sub {
            my $consent = GDPR::IAB::TCFv2->Parse(
                'COyfVVoOyfVVoADACHENAwCAAAAAAAAAAAAAE5QBgALgAqgD8AQACSwEygJyAnSAMABgAFkAgQCDASeAmYBOgAA',
                json => {
                    verbose        => 0,
                    compact        => 1,
                    use_epoch      => 0,
                    boolean_values => [ 0, 1 ],
                    date_format    => '%Y%m%d',    # yyymmdd
                },
            );

            my $got      = $consent->TO_JSON();
            my $expected = _fixture_range_compact(
                created      => 20200427,
                last_updated => 20200427,
            );

t/03-json-range.t  view on Meta::CPAN

            done_testing;
          };

        subtest "should convert data to json using epoch date format" => sub {
            my $consent = GDPR::IAB::TCFv2->Parse(
                'COyfVVoOyfVVoADACHENAwCAAAAAAAAAAAAAE5QBgALgAqgD8AQACSwEygJyAnSAMABgAFkAgQCDASeAmYBOgAA',
                json => {
                    verbose        => 0,
                    compact        => 1,
                    use_epoch      => 1,
                    boolean_values => [ 0, 1 ],
                },
            );


            my $got      = $consent->TO_JSON();
            my $expected = _fixture_range_compact(
                created      => 1587946020,
                last_updated => 1587946020,
            );

t/03-json-range.t  view on Meta::CPAN

      "should convert data to json using default (non-compact) and 0/1 as booleans"
      => sub {

        subtest "default non verbose, date as iso 8601" => sub {
            my $consent = GDPR::IAB::TCFv2->Parse(
                'COyfVVoOyfVVoADACHENAwCAAAAAAAAAAAAAE5QBgALgAqgD8AQACSwEygJyAnSAMABgAFkAgQCDASeAmYBOgAA',
                json => {
                    verbose        => 0,
                    compact        => 0,
                    use_epoch      => 0,
                    boolean_values => [ 0, 1 ],
                },
            );

            ok $consent->vendor_consent(23);

            my $got      = $consent->TO_JSON();
            my $expected = _fixture_range_default();

            is_deeply $got, $expected, "must return the json hashref";

            done_testing;
        };

        subtest "default verbose, date as iso 8601" => sub {
            my $consent = GDPR::IAB::TCFv2->Parse(
                'COyfVVoOyfVVoADACHENAwCAAAAAAAAAAAAAE5QBgALgAqgD8AQACSwEygJyAnSAMABgAFkAgQCDASeAmYBOgAA',
                json => {
                    verbose        => 1,
                    compact        => 0,
                    use_epoch      => 0,
                    boolean_values => [ 0, 1 ],
                },
            );

            ok $consent->vendor_consent(23);

            my $got      = $consent->TO_JSON();
            my $expected = _fixture_range_verbose();

            is_deeply $got, $expected, "must return the json hashref";

t/03-json-range.t  view on Meta::CPAN

      };

    subtest "publisher section" => sub {
        subtest "publisher section without publisher_tc" => sub {
            my $consent = GDPR::IAB::TCFv2->Parse(
                'COwAdDhOwAdDhN4ABAENAPCgAAQAAv___wAAAFP_AAp_4AI6ACACAA',
                json => {
                    verbose        => 0,
                    compact        => 1,
                    use_epoch      => 0,
                    boolean_values => [ 0, 1 ],
                },
            );

            my $got = $consent->TO_JSON;
            my $expected =
              { "publisher" => { "restrictions" => { "7" => { "32" => 1 } } }
              };

            is_deeply $got->{publisher}, $expected->{publisher},
              "must return the same publisher restriction section";

t/03-json-range.t  view on Meta::CPAN

            done_testing;
        };
        subtest "publisher section with publisher_tc" => sub {
            subtest "without custom purposes" => sub {
                my $consent = GDPR::IAB::TCFv2->Parse(
                    'COwAdDhOwAdDhN4ABAENAPCgAAQAAv___wAAAFP_AAp_4AI6ACACAA.argAC0gAAAAAAAAAAAA',
                    json => {
                        verbose        => 0,
                        compact        => 1,
                        use_epoch      => 0,
                        boolean_values => [ 0, 1 ],
                    },
                );

                my $got      = $consent->TO_JSON;
                my $expected = {
                    "publisher" => {
                        "consents"             => [ 2, 4, 6, 8, 9, 10 ],
                        "legitimate_interests" => [ 2, 4, 5, 7, 10 ],
                        "custom_purposes"      => {
                            "consents"             => [],

t/03-json-range.t  view on Meta::CPAN

                done_testing;
            };

            subtest "with custom purposes" => sub {
                my $consent = GDPR::IAB::TCFv2->Parse(
                    'COwAdDhOwAdDhN4ABAENAPCgAAQAAv___wAAAFP_AAp_4AI6ACACAA.YAAAAAAAAXA',
                    json => {
                        verbose        => 0,
                        compact        => 1,
                        use_epoch      => 0,
                        boolean_values => [ 0, 1 ],
                    },
                );

                my $got      = $consent->TO_JSON;
                my $expected = {
                    "publisher" => {
                        "consents"             => [],
                        "legitimate_interests" => [],
                        "custom_purposes"      => {
                            "consents"             => [ 1, 2 ],

t/03-json-range.t  view on Meta::CPAN

        done_testing;
    };

    subtest "TO_JSON method should return the same hashref " => sub {
        my $consent = GDPR::IAB::TCFv2->Parse(
            'COyfVVoOyfVVoADACHENAwCAAAAAAAAAAAAAE5QBgALgAqgD8AQACSwEygJyAnSAMABgAFkAgQCDASeAmYBOgAA',
            json => {
                verbose        => 0,
                compact        => 1,
                use_epoch      => 0,
                boolean_values => [ 0, 1 ],
            },
        );


        my $got1 = $consent->TO_JSON();
        my $got2 = $consent->TO_JSON();

        is_deeply $got1, $got2, "must return the same hashref";

        done_testing;



( run in 0.859 second using v1.01-cache-2.11-cpan-9ff20fc0ed8 )