PHP code example of headio / phalcon-service-layer

1. Go to this page and download the library: Download headio/phalcon-service-layer 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/ */

    

headio / phalcon-service-layer example snippets


declare(strict_types=1);

namespace App\Service;

use App\Domain\Repository\Foo as Repository;
use App\Domain\Service\Foo as Service;
use Headio\Phalcon\ServiceLayer\Repository\Factory;
use Phalcon\Di\ServiceProviderInterface;
use Phalcon\Di\DiInterface;

class Foo implements ServiceProviderInterface
{
    public function register(DiInterface $di): void
    {
        $di->setShared(
            'fooService',
            function () {
                $repository = Factory::create(Repository::class)
                $service = new Service($repository);

                return $service;
            }
        );
    }
}

declare(strict_types=1);

namespace App\Module\Admin;

use App\Domain\Repository\Foo as Repository;
use App\Domain\Service\Foo as Service;
use Headio\Phalcon\ServiceLayer\Repository\Factory;
use Phalcon\Di\DiInterface;
use Phalcon\Loader;
use Phalcon\Mvc\ModuleDefinitionInterface;

class Module implements ModuleDefinitionInterface
{
    /**
     * {@inheritDoc}
     */
    public function registerAutoloaders(DiInterface $container = null)
    {
    }

    /**
     * {@inheritDoc}
     */
    public function registerServices(DiInterface $container)
    {
        $container->setShared(
            'fooService',
            function () use ($container) {
                $repository = Factory::create(Repository::class);
                $service = new Service($repository);

                return $service;
            }
        );
    }
}

namespace App\Module\Admin\Foo;

use Phalcon\Mvc\Controller;

class Foo extends Controller
{
    private FooInterface $service;

    /**
     * Inject service layer dependencies
     */
    public function onConstruct(): void
    {
        $this->service = $this->getDI()->get('fooService');
    }
}

declare(strict_types=1);

namespace App\Domain\Service\Foo;

use App\Domain\Repository\FooInterface;
use App\Domain\Service\FooInterface as ServiceInterface;
use Phalcon\Di\Injectable;
use Phalcon\Http\ResponseInterface;

class Foo extends Injectable implements ServiceInterface
{
    public function __construct(private FooInterface $repository)
    {
    }

    /**
     * Delete a model instance
     */
    public function deleteModel(int $id): ResponseInterface
    {
        $model = $this->repository->findByPk($id);

        if ($this->delete($model)) {
            $this->flashSession->notice('Task completed');
            return $this->response->redirect(['for' => 'adminFoos']);
        }
    }
}

declare(strict_types=1);

namespace App\Domain\Repository;

use App\Domain\Model\Foo as Model;
use App\Domain\Repository\FooInterface;
use Headio\Phalcon\ServiceLayer\Repository\QueryRepository;

class Foo extends QueryRepository implements FooInterface
{
    /**
     * Return the model name managed by this repository.
     */
    protected function getModelName(): string
    {
        return Model::class;
    }
}

declare(strict_types=1);

namespace Headio\Phalcon\Repository\Repository;

use Headio\Phalcon\ServiceLayer\Model\CriteriaInterface;
use Headio\Phalcon\ServiceLayer\Model\ModelInterface;
use Phalcon\Mvc\Model\ResultsetInterface;
use Phalcon\Mvc\Model\Query\BuilderInterface;

interface RepositoryInterface
{
    /**
     * Return an instance of the query criteria pre-populated
     * with the model managed by this repository.
     */
    public function createCriteria(): CriteriaInterface;

    /**
     * Return an instance of the query builder.
     */
    public function createBuilder(array $params = null): BuilderInterface;

    /**
     * Fetch a column value by query criteria from storage.
     */
    public function fetchColumn(CriteriaInterface $criteria): mixed;

    /**
     * Fetch records by query criteria from storage.
     */
    public function find(CriteriaInterface $criteria): ResultsetInterface;

    /**
     * Fetch record by primary key from storage.
     */
    public function findByPk(int $id): ModelInterface;

    /**
     * Fetch first record by query criteria from storage.
     */
    public function findFirst(CriteriaInterface $criteria): ModelInterface;

    /**
     * Fetch first record by property name from storage.
     */
    public function findFirstBy(string $property, mixed $value): ModelInterface;

    /**
     * Return the fully qualified (or unqualified) class name
     * for the model managed by this repository.
     */
    public function getModel(bool $unqualified = false): string;
}

declare(strict_types=1);

namespace App\Domain\Repository;

use App\Domain\Model\Foo as Model;
use App\Domain\Repository\FooInterface;
use Headio\Phalcon\ServiceLayer\Repository\QueryRepository;
use Headio\Phalcon\ServiceLayer\Repository\Traits\RelationshipTrait;

class Foo extends QueryRepository implements FooInterface
{
    use RelationshipTrait;

    /**
     * Return the model name managed by this repository.
     */
    protected function getModelName(): string
    {
        return Model::class;
    }
}

declare(strict_types=1);

namespace App\Domain\Repository;

use App\Domain\Model\User as Model;
use Headio\Phalcon\ServiceLayer\Model\ModelInterface;
use Headio\Phalcon\ServiceLayer\Repository\QueryRepository;
use Headio\Phalcon\ServiceLayer\Repository\Traits\CacheableTrait;
use Phalcon\Events\EventsAwareInterface;

class User extends QueryRepository implements UserInterface, EventsAwareInterface
{
    use CacheableTrait;

    /**
     * Return the model name managed by this repository.
     */
    protected function getModelName(): string
    {
        return Model::class;
    }
}

declare(strict_types=1);

namespace App\Service;

use App\Domain\Repository\Foo as Repository;
use App\Domain\Service\Foo as Service;
use Headio\Phalcon\ServiceLayer\Cache\Listener\CacheListener;
use Headio\Phalcon\ServiceLayer\Repository\Factory;
use Phalcon\Di\ServiceProviderInterface;
use Phalcon\Di\DiInterface;

class Foo implements ServiceProviderInterface
{
    public function register(DiInterface $di): void
    {
        $di->setShared(
            'fooService',
            function () {
                $eventsManager = new EventsManager();
                // factory instantiation
                $repository = Factory::create(Repository::class);
                $repository->setEventsManager($eventsManager);
                $cacheManager = $this->get('cacheManager');
                // attach the cache event listener and inject the
                // cache manager dependency
                $eventsManager->attach(
                    'cache',
                    new CacheListener(
                        $cacheManager
                    )
                );
                $service = new Service($repository);

                return $service;
            }
        );
    }
}

/**
 * This event listener provides caching functionality for repositories.
 */
class CacheListener
{
    public function __construct(private ManagerInterface $manager)
    {
    }

    /**
     * Appends a cache declaration to a Phalcon query instance.
     */
    public function append(
        EventInterface $event,
        RepositoryInterface $repository,
        QueryInterface $query,
    ): QueryInterface;

    /**
     * Fetches data from cache or storage using the cache-aside
     * strategy.
     */
    public function fetch(
        EventInterface $event,
        RepositoryInterface $repository,
        array $context,
    ): ModelInterface|ResultsetInterface;
}

trait CacheableTrait
{
    /**
     * Fetch first record by query criteria from cache or storage.
     *
     * @throws NotFoundException
     */
    public function findFirst(CriteriaInterface $criteria): ModelInterface
    {
        $query = $criteria
            ->createBuilder()
            ->getQuery()
            ->setUniqueRow(true)
        ;
        $this->eventsManager->fire('cache:append', $this, $query);
        $model = $query->execute();

        if (!$model instanceof ModelInterface) {
            throw new NotFoundException('404 Not Found');
        }

        return $model;
    }

    /**
     * Fetch data from cache or storage.
     */
    public function fromCache(
        QueryInterface|array $query,
        Closure $callable,
        DateInterval|int $lifetime = null,
    ): ResultsetInterface|ModelInterface|null {
        $key = $this->cacheManager->generateKey(
            $this->getModel(),
            $query,
        );

        return $this->eventsManager->fire(
            'cache:fetch',
            $this,
            [$key, $callable],
        );
    }

declare(strict_types=1);

namespace Headio\Phalcon\ServiceLayer\Model;

use Phalcon\Di\DiInterface;
use Phalcon\Mvc\Model\CriteriaInterface;

interface ModelInterface
{
    /**
     * Return the model primary key attribute.
     */
    public function getPrimaryKey(): string;

    /**
     * Return the property binding type for a given property.
     */
    public function getPropertyBindType(string $property): int;

    /**
     * Return the model validation errors as an array representation.
     */
    public function getValidationErrors(): array;

    /**
     * Return an instance of the query criteria pre-populated
     * with the model.
     */
    public static function query(DiInterface $container = null): CriteriaInterface;
}