PHP code example of roadiz / abstract-api-theme

1. Go to this page and download the library: Download roadiz/abstract-api-theme library. Choose the download type require.

2. Extract the ZIP file and open the index.php.

3. Add this code to the index.php.
    
        
<?php
require_once('vendor/autoload.php');

/* Start to develop here. Best regards https://php-download.com/ */

    

roadiz / abstract-api-theme example snippets


# AppKernel.php
/**
 * {@inheritdoc}
 */
public function register(\Pimple\Container $container)
{
    parent::register($container);

    /*
     * Add your own service providers.
     */
    $container->register(new \Themes\AbstractApiTheme\Services\AbstractApiServiceProvider());
}


declare(strict_types=1);

namespace Themes\MyApiTheme;

use Symfony\Component\HttpFoundation\RequestMatcher;
use Pimple\Container;
use Themes\AbstractApiTheme\AbstractApiThemeTrait;

class MyApiThemeApp extends FrontendController
{
    use AbstractApiThemeTrait;

    protected static $themeName = 'My API theme';
    protected static $themeAuthor = 'REZO ZERO';
    protected static $themeCopyright = 'REZO ZERO';
    protected static $themeDir = 'MyApiTheme';
    protected static $backendTheme = false;
    
    public static $priority = 10;
    
    /**
     * @inheritDoc
     */
    public static function addDefaultFirewallEntry(Container $container)
    {
        /*
         * API MUST be the first request matcher
         */
        $requestMatcher = new RequestMatcher(
            '^'.preg_quote($container['api.prefix']).'/'.preg_quote($container['api.version'])
        );

        $container['accessMap']->add(
            $requestMatcher,
            [$container['api.base_role']]
        );

        /*
         * Add default API firewall entry.
         */
        $container['firewallMap']->add(
            $requestMatcher, // launch firewall rules for any request within /api/1.0 path
            [$container['api.firewall_listener']],
            $container['api.exception_listener'] // do not forget to add exception listener to enforce accessMap rules
        );
        /*
         * OR add OAuth2 API firewall entry.
         */
        // $container['firewallMap']->add(
        //     $requestMatcher, // launch firewall rules for any request within /api/1.0 path
        //     [$container['api.oauth2_firewall_listener']],
        //     $container['api.exception_listener'] // do not forget to add exception listener to enforce accessMap rules
        // );

        // Do not forget to register default frontend entries
        // AFTER API not to lose preview feature
        parent::addDefaultFirewallEntry($container);
    }
}

/*
 * Enable grant types
 */
$container->extend(AuthorizationServer::class, function (AuthorizationServer $server, Container $c) {
    // Enable the client credentials grant on the server
    $server->enableGrantType(
        new \League\OAuth2\Server\Grant\ClientCredentialsGrant(),
        new \DateInterval('PT1H') // access tokens will expire after 1 hour
    );
    // Enable the authorization grant on the server
    $authCodeGrant = new \League\OAuth2\Server\Grant\AuthCodeGrant(
        $c[AuthCodeRepositoryInterface::class],
        $c[RefreshTokenRepositoryInterface::class],
        new \DateInterval('PT10M') // authorization_codes will expire after 10 min
    );
    $server->enableGrantType(
        $authCodeGrant,
        new \DateInterval('PT3H') // access tokens will expire after 3 hours
    );
    return $server;
});

/**
 * @return array
 */
$container['api.cors_options'] = [
    'allow_credentials' => true,
    'allow_origin' => ['*'],
    'allow_headers' => true,
    'origin_regex' => false,
    'allow_methods' => ['GET'],
    'expose_headers' => ['link', 'etag'],
    'max_age' => 60*60*24
];

// In your application/theme service provider
$container['api.use_cache_tags'] = true;

# Any JMS\Serializer\EventDispatcher\EventSubscriberInterface implementation…

$exclusionStrategy = $context->getExclusionStrategy() ?? 
    new \JMS\Serializer\Exclusion\DisjunctExclusionStrategy();
/** @var array<string> $groups */
$groups = $context->hasAttribute('groups') ? 
    $context->getAttribute('groups') : 
    [];
$groups = array_unique(array_merge($groups, [
    'walker',
    'children'
]));
$propertyMetadata = new \JMS\Serializer\Metadata\StaticPropertyMetadata(
    'Collection',
    'children',
    [],
    $groups
);
# Check if virtual property children has been requested with properties[] filter…
if (!$exclusionStrategy->shouldSkipProperty($propertyMetadata, $context)) {
    $blockWalker = BlockNodeSourceWalker::build(
        $nodeSource,
        $this->get(NodeSourceWalkerContext::class),
        4, // max graph level
        $this->get('nodesSourcesUrlCacheProvider')
    );
    $visitor->visitProperty(
        $propertyMetadata,
        $blockWalker->getChildren()
    );
}

# Any JMS\Serializer\EventDispatcher\EventSubscriberInterface implementation…

public function onPostSerialize(\JMS\Serializer\EventDispatcher\ObjectEvent $event): void
{
    $context = $event->getContext();
    
    /** @var \Symfony\Component\HttpFoundation\Request $request */
    $request = $context->hasAttribute('request') ? $context->getAttribute('request') : null;
    
    /** @var \RZ\Roadiz\Contracts\NodeType\NodeTypeInterface|null $nodeType */
    $nodeType = $context->hasAttribute('nodeType') ? $context->getAttribute('nodeType') : null;
    
    /** @var \RZ\Roadiz\Core\AbstractEntities\TranslationInterface|null $translation */
    $translation = $context->hasAttribute('translation') ? $context->getAttribute('translation') : null;
    
    /** @var array<string> $groups */
    $groups = $context->hasAttribute('groups') ? $context->getAttribute('groups') : [];
}


declare(strict_types=1);

namespace App\Breadcrumbs;

use RZ\Roadiz\Core\Entities\NodesSources;
use Themes\AbstractApiTheme\Breadcrumbs\BreadcrumbsFactoryInterface;
use Themes\AbstractApiTheme\Breadcrumbs\BreadcrumbsInterface;
use Themes\AbstractApiTheme\Breadcrumbs\Breadcrumbs;

final class BreadcrumbsFactory implements BreadcrumbsFactoryInterface
{
    /**
     * @param NodesSources|null $nodesSources
     * @return BreadcrumbsInterface|null
     */
    public function create(?NodesSources $nodesSources): ?BreadcrumbsInterface
    {
        if (null === $nodesSources ||
            null === $nodesSources->getNode() ||
            null === $nodesSources->getNode()->getNodeType() ||
            !$nodesSources->getNode()->getNodeType()->isReachable()) {
            return null;
        }
        $parents = [];

        while (null !== $nodesSources = $nodesSources->getParent()) {
            if (null !== $nodesSources->getNode() &&
                $nodesSources->getNode()->isPublished() &&
                $nodesSources->getNode()->isVisible()) {
                $parents[] = $nodesSources;
            }
        }
        return new Breadcrumbs(array_reverse($parents));
    }
}

# App\AppServiceProvider
$container[BreadcrumbsFactoryInterface::class] = function (Container $c) {
    return new BreadcrumbsFactory();
};
json
{
    "hydra:member": [
        {
            "slug": "home",
            "@type": "Page",
            "node": {
                "nodeName": "accueil",
                "tags": []
            },
            "title": "Accueil",
            "publishedAt": "2021-01-18T23:32:39+01:00",
            "@id": "http://example.test/dev.php/api/1.0/page/2/fr",
            "url": "/dev.php/home"
        }
    ],
    "hydra:totalItems": 1,
    "@id": "/api/1.0/page",
    "@type": "hydra:Collection",
    "hydra:view": {
        "@id": "/api/1.0/page",
        "@type": "hydra:PartialCollectionView"
    }
}
json
{
    "hydra:member": {
        "2021": {
            "2021-01": "2021-01-01T00:00:00+01:00"
        },
        "2020": {
            "2020-12": "2020-12-01T00:00:00+01:00",
            "2020-10": "2020-10-01T00:00:00+02:00",
            "2020-07": "2020-07-01T00:00:00+02:00"
        }
    },
    "@id": "/api/1.0/event/archives",
    "@type": "hydra:Collection",
    "hydra:view": {
        "@id": "/api/1.0/event/archives",
        "@type": "hydra:PartialCollectionView"
    }
}