autowp/autowp

View on GitHub
module/Application/src/Model/Log.php

Summary

Maintainability
C
1 day
Test Coverage
F
37%
<?php

namespace Application\Model;

use Autowp\Commons\Db\Table\Row;
use Autowp\User\Model\User;
use Laminas\Db\Adapter\Adapter;
use Laminas\Db\Adapter\Exception\InvalidQueryException;
use Laminas\Db\Sql;
use Laminas\Db\TableGateway\TableGateway;
use Laminas\Paginator;

use function array_replace;
use function strpos;

class Log
{
    private const EVENTS_PER_PAGE = 40;

    private TableGateway $eventTable;

    private Picture $picture;

    private TableGateway $eventArticleTable;

    private TableGateway $eventItemTable;

    private TableGateway $eventPictureTable;

    private TableGateway $eventUserTable;

    private TableGateway $itemTable;

    private User $userModel;

    public function __construct(
        Picture $picture,
        TableGateway $logTable,
        TableGateway $eventArticleTable,
        TableGateway $eventItemTable,
        TableGateway $eventPictureTable,
        TableGateway $eventUserTable,
        TableGateway $itemTable,
        User $userModel
    ) {
        $this->itemTable         = $itemTable;
        $this->eventTable        = $logTable;
        $this->picture           = $picture;
        $this->eventArticleTable = $eventArticleTable;
        $this->eventItemTable    = $eventItemTable;
        $this->eventPictureTable = $eventPictureTable;
        $this->eventUserTable    = $eventUserTable;
        $this->userModel         = $userModel;
    }

    public function addEvent(int $userId, string $message, array $objects): void
    {
        $this->eventTable->insert([
            'description'  => $message,
            'user_id'      => $userId,
            'add_datetime' => new Sql\Expression('NOW()'),
        ]);
        $id = $this->eventTable->getLastInsertValue();

        $this->assign($id, $objects);
    }

    private function assign(int $id, array $items): void
    {
        $defaults = [
            'items'    => [],
            'pictures' => [],
            'users'    => [],
            'articles' => [],
        ];
        $items    = array_replace($defaults, $items);

        foreach ((array) $items['items'] as $item) {
            try {
                $this->eventItemTable->insert([
                    'log_event_id' => $id,
                    'item_id'      => $item,
                ]);
            } catch (InvalidQueryException $e) {
                if (strpos($e->getMessage(), 'Duplicate entry') === false) {
                    throw $e;
                }
            }
        }

        foreach ((array) $items['pictures'] as $item) {
            try {
                $this->eventPictureTable->insert([
                    'log_event_id' => $id,
                    'picture_id'   => $item,
                ]);
            } catch (InvalidQueryException $e) {
                if (strpos($e->getMessage(), 'Duplicate entry') === false) {
                    throw $e;
                }
            }
        }

        foreach ((array) $items['users'] as $item) {
            try {
                $this->eventUserTable->insert([
                    'log_event_id' => $id,
                    'user_id'      => $item,
                ]);
            } catch (InvalidQueryException $e) {
                if (strpos($e->getMessage(), 'Duplicate entry') === false) {
                    throw $e;
                }
            }
        }

        foreach ((array) $items['articles'] as $item) {
            try {
                $this->eventArticleTable->insert([
                    'log_event_id' => $id,
                    'article_id'   => $item,
                ]);
            } catch (InvalidQueryException $e) {
                if (strpos($e->getMessage(), 'Duplicate entry') === false) {
                    throw $e;
                }
            }
        }
    }

    public function getList(array $options): array
    {
        $defaults = [
            'article_id' => null,
            'item_id'    => null,
            'picture_id' => null,
            'user_id'    => null,
            'page'       => null,
            'language'   => 'en',
        ];
        $options  = array_replace($defaults, $options);

        $select = new Sql\Select($this->eventTable->getTable());
        $select->order(['add_datetime DESC', 'id DESC']);

        $articleId = (int) $options['article_id'];
        if ($articleId) {
            $select
                ->join('log_events_articles', 'log_events.id = log_events_articles.log_event_id', [])
                ->where(['log_events_articles.article_id = ?' => $articleId]);
        }

        $itemId = (int) $options['item_id'];
        if ($itemId) {
            $select
                ->join('log_events_item', 'log_events.id = log_events_item.log_event_id', [])
                ->where(['log_events_item.item_id = ?' => $itemId]);
        }

        $pictureId = (int) $options['picture_id'];
        if ($pictureId) {
            $select
                ->join('log_events_pictures', 'log_events.id = log_events_pictures.log_event_id', [])
                ->where(['log_events_pictures.picture_id = ?' => $pictureId]);
        }

        $userId = (int) $options['user_id'];
        if ($userId) {
            $select->where(['log_events.user_id = ?' => $userId]);
        }

        /** @var Adapter $adapter */
        $adapter   = $this->eventTable->getAdapter();
        $paginator = new Paginator\Paginator(
            new Paginator\Adapter\LaminasDb\DbSelect($select, $adapter)
        );

        $paginator
            ->setItemCountPerPage(self::EVENTS_PER_PAGE)
            ->setCurrentPageNumber($options['page']);

        $events = [];
        foreach ($paginator->getCurrentItems() as $event) {
            $select = new Sql\Select($this->itemTable->getTable());
            $select->join('log_events_item', 'item.id = log_events_item.item_id', [])
                ->where(['log_events_item.log_event_id' => $event['id']]);

            $itemRows = [];
            foreach ($this->itemTable->selectWith($select) as $row) {
                $itemRows[] = $row;
            }

            $pictureRows = $this->picture->getRows([
                'log' => $event['id'],
            ]);

            $events[] = [
                'user'     => $this->userModel->getRow((int) $event['user_id']),
                'date'     => Row::getDateTimeByColumnType('timestamp', $event['add_datetime']),
                'desc'     => $event['description'],
                'items'    => $itemRows,
                'pictures' => $pictureRows,
            ];
        }

        return [
            'paginator' => $paginator,
            'events'    => $events,
        ];
    }
}