ForumPostRepository.php 5.54 KB
<?php

namespace FootyRoom\Repositories;

use DateTime;
use FootyRoom\Core\ForumPost\ForumPost;
use FootyRoom\Support\AutoMapper;
use Illuminate\Database\Connection;

class ForumPostRepository
{
    /**
     * @var \Illuminate\Database\Connection
     */
    protected $mysql;

    /**
     * Constructor.
     *
     * @param \Illuminate\Database\Connection $mysql
     */
    public function __construct(Connection $mysql)
    {
        $this->mysql = $mysql;
    }

    /**
     * Finds post by id.
     *
     * @param int $id
     *
     * @return \FootyRoom\Core\ForumPost\ForumPost
     */
    public function findById($id)
    {
        $postDto = $this->mysql

        ->table('wp_posts')
        ->join('wp_term_relationships', 'wp_posts.id', '=', 'wp_term_relationships.object_id')
        ->select([
            'id',
            'post_title as title',
            'post_name as slug',
            'post_author as userId',
            'post_title as title',
            'comment_status as discussionStatus',
            'post_status as status',
            'term_taxonomy_id as categoryId',
            'post_content as content',
            'post_date as date',
            'guid',
        ])
        ->where('ID', '=', $id)
        ->first();

        if (!$postDto) {
            return null;
        }

        $postDto->date = new DateTime($postDto->date);

        $post = AutoMapper::map($postDto, ForumPost::class);

        return $post;
    }

    /**
     * Finds forum posts by title.
     *
     * @param string $q
     * @param int $offset
     * @param int $limit
     *
     * @return object[]|null
     */
    public function findByTitle($q, $offset, $limit)
    {
        return $this->mysql

        ->table('wp_posts AS p')
        ->select(['id', 'post_title as title', 'post_name as slug', 'comment_count as commentCount'])
        ->join('wp_term_relationships AS tr', 'p.id', '=', 'tr.object_id')
        ->join('wp_terms AS t', 'tr.term_taxonomy_id', '=', 't.term_id')
        ->where('p.post_status', '=', 'publish')
        ->where('p.post_type', '=', 'post')
        ->where('p.post_title', 'LIKE', "%$q%")
        ->where('t.term_group', '=', 100)
        ->orderBy('p.id', 'desc')
        ->offset($offset)
        ->limit($limit)
        ->get();
    }

    /**
     * Saves new forum post.
     *
     * @param \FootyRoom\Core\ForumPost\ForumPost $post
     *
     * @return \FootyRoom\Core\ForumPost\ForumPost | null
     */
    public function create(ForumPost $post)
    {
        $options = [
            'post_status' => $post->isPublished() ? 'publish' : 'draft',
            'post_type' => 'post',
            'post_author' => $post->getUserId(),
            'post_name' => $post->getSlug(),
            'ping_status' => '',
            'post_parent' => 0,
            'post_password' => '',
            'post_content' => '',
            'post_title' => $post->getTitle(),
            'post_date' => $post->getDate()->format('c'),
            'post_date_gmt' => $post->getDate()->format('c'),
        ];

        $postId = $this->mysql

        ->table('wp_posts')
        ->insertGetId($options);

        AutoMapper::setValue($post, 'id', $postId);

        // Associate this post with its category.
        $this->assignCategory($post->getId(), $post->getCategoryId());

        return $post;
    }

    /**
     * Update post's status.
     *
     * @param \FootyRoom\Core\ForumPost\ForumPost $post
     */
    public function updateStatus(ForumPost $post)
    {
        $this->mysql

        ->table('wp_posts')
        ->where('id', '=', $post->getId())
        ->update([
            'post_status' => $post->isPublished() ? 'publish' : 'draft',
        ]);
    }

    /*
     * Updates settings of a specified forum post.
     *
     * @param \FootyRoom\Core\ForumPost\ForumPost $post
     */
    public function updateSettings(ForumPost $post)
    {
        if (!$post->isSticky()) {
            $sticky = 0;
        } else {
            $sticky = $post->isLocalSticky() ? 1 : 5;
        }

        $update = [
            'sticky' => $sticky,
            'post_name' => $post->getSlug(),
            'comment_status' => $post->isDiscussionOpen() ? 'open' : 'closed',
            'post_title' => $post->getTitle(),
            'post_author' => $post->getUserId(),
            'post_status' => $post->isPublished() ? 'publish' : 'draft',
        ];

        $this->mysql

        ->table('wp_posts')
        ->where('id', '=', $post->getId())
        ->update($update);

        // Associate this post with its category.
        $this->updateCategory($post->getId(), $post->getCategoryId());
    }

    /**
     * Update category of existing post.
     *
     * @param int $postId
     * @param int $categoryId
     */
    protected function updateCategory($postId, $categoryId)
    {
        $this->mysql

        ->table('wp_term_relationships')
        ->where('object_id', '=', $postId)
        ->update([
            'term_taxonomy_id' => $categoryId,
        ]);
    }

    /**
     * Assign category to new post.
     *
     * @param int $postId
     * @param int $categoryId
     */
    protected function assignCategory($postId, $categoryId)
    {
        $this->mysql

        ->table('wp_term_relationships')
        ->insert([
            'object_id' => $postId,
            'term_taxonomy_id' => $categoryId,
        ]);
    }

    /**
     * Increment posts comment count.
     *
     * @param int $postId
     */
    public function incrementCommentCount($postId)
    {
        $this->mysql

        ->table('wp_posts')
        ->where('ID', '=', $postId)
        ->increment('comment_count');
    }
}