netglue/prismic-php-kit

View on GitHub
src/Prismic/Document/Fragment/Slice.php

Summary

Maintainability
A
1 hr
Test Coverage
A
100%
<?php

declare(strict_types=1);

namespace Prismic\Document\Fragment;

use Prismic\Exception\InvalidArgumentException;
use Prismic\LinkResolver;

use function count;
use function implode;

class Slice implements CompositeFragmentInterface
{

    use HtmlHelperTrait;

    /**
     * @var FragmentCollection
     */
    private $primary;

    /**
     * @var Group
     */
    private $group;

    /** @var string */
    private $type;

    /** @var string|null */
    private $label;

    private function __construct(
        string $type,
        FragmentCollection $primary,
        Group $group,
        ?string $label = null
    ) {
        $this->type    = $type;
        $this->label   = $label;
        $this->primary = $primary;
        $this->group   = $group;
    }

    public static function factory($value, LinkResolver $linkResolver) : FragmentInterface
    {
        return static::fromJson($value, $linkResolver);
    }

    public static function fromJson($value, LinkResolver $linkResolver) : self
    {
        // Type and Label are the same for V1 & V2
        $type    = isset($value->slice_type)
                 ? (string) $value->slice_type
                 : null;
        $label   = isset($value->slice_label)
                 ? (string) $value->slice_label
                 : null;

        if (! $type) {
            throw new InvalidArgumentException('No Slice type could be determined from the payload');
        }

        // V1
        $group   = isset($value->repeat)
                 ? Group::factory($value->repeat, $linkResolver)
                 : null;
        $primary = isset($value->{'non-repeat'})
                 ? FragmentCollection::factory($value->{'non-repeat'}, $linkResolver)
                 : null;
        /**
         * In much older versions of the API (Before "Composite Slices"), slices
         * had a 'value' property which contained the repeatable group
         */
        if (! $group && isset($value->value) && isset($value->value->type) && $value->value->type === 'Group') {
            $group = Group::factory($value->value, $linkResolver);
        }

        // V2
        $group   = isset($value->items)
                 ? Group::factory($value->items, $linkResolver)
                 : $group;
        $primary = isset($value->primary)
                 ? FragmentCollection::factory($value->primary, $linkResolver)
                 : $primary;

        $group = $group ? $group : Group::emptyGroup();
        $primary = $primary ? $primary : FragmentCollection::emptyCollection();

        return new static($type, $primary, $group, $label);
    }

    public function getType() : string
    {
        return $this->type;
    }

    public function getLabel() :? string
    {
        return $this->label;
    }

    public function getPrimary() : FragmentCollection
    {
        return $this->primary;
    }

    public function getItems() : Group
    {
        return $this->group;
    }

    public function asText() :? string
    {
        $data = [];
        $primary = $this->primary->asText();
        if ($primary) {
            $data[] = $primary;
        }
        $group = $this->group->asText();
        if ($group) {
            $data[] = $group;
        }
        return count($data) >= 1
            ? implode(\PHP_EOL, $data)
            : null;
    }

    public function asHtml() :? string
    {
        $primary = $this->primary->asHtml();
        $group   = $this->group->asHtml();
        if (empty($primary) && empty($group)) {
            return null;
        }

        $attributes = [
            'data-slice-type' => $this->type,
        ];
        if ($this->label) {
            $attributes['class'] = $this->label;
        }
        $data = [
            sprintf('<div%s>', $this->htmlAttributes($attributes)),
        ];
        if ($primary) {
            $data[] = $primary;
        }
        if ($group) {
            $data[] = $group;
        }
        $data[] = '</div>';
        return implode(\PHP_EOL, $data);
    }
}