Passed
Push — main ( efbc77...d47715 )
by Marc
03:46
created

ModelFactory::createContentObject()   B

Complexity

Conditions 6
Paths 13

Size

Total Lines 27
Code Lines 21

Duplication

Lines 0
Ratio 0 %

Importance

Changes 1
Bugs 0 Features 0
Metric Value
cc 6
eloc 21
c 1
b 0
f 0
nc 13
nop 1
dl 0
loc 27
rs 8.9617
1
<?php declare(strict_types=1);
2
namespace html_go\model;
3
4
use DateTimeInterface;
5
use InvalidArgumentException;
6
use html_go\exceptions\InternalException;
7
use html_go\markdown\MarkdownParser;
8
use html_go\indexing\IndexManager;
9
10
/**
11
 * Responsible for creating <code>Content</code> objects ready to be used in templates.
12
 * @author Marc L. Veary
13
 * @since 1.0
14
 */
15
final class ModelFactory
16
{
17
    private Config $config;
18
    private MarkdownParser $parser;
19
    private IndexManager $manager;
20
21
    /**
22
     * ModelFactory constructor.
23
     * @param Config $config
24
     * @param MarkdownParser $parser Implementation of the
25
     * <code>MarkdownParser</code> interface.
26
     */
27
    public function __construct(Config $config, MarkdownParser $parser, IndexManager $manager) {
28
        $this->config = $config;
29
        $this->parser = $parser;
30
        $this->manager = $manager;
31
    }
32
33
    /**
34
     * Create a content object (stdClass) from an index <code>Element</code>
35
     * object.
36
     * @param \stdClass $indexElement As obtained from the <code>IndexManager</code>
37
     * @return \stdClass
38
     */
39
    public function createContentObject(\stdClass $indexElement): \stdClass {
40
        $contentObject = $this->loadDataFile($indexElement);
41
        $contentObject->key = $indexElement->key;
42
        if (!empty($indexElement->category)) {
43
            if ($this->manager->elementExists($indexElement->category) === false) {
44
                throw new \UnexpectedValueException("Content's [$contentObject->key] category [$indexElement->category] does not exist!");
45
            }
46
            $element = $this->manager->getElementFromSlugIndex($indexElement->category);
47
            $category = $this->loadDataFile($element);
48
            $contentObject->category = $category;
49
        }
50
        if (isset($indexElement->tags)) {
51
            $contentObject->tags = $indexElement->tags;
52
        }
53
        if (isset($indexElement->date)) {
54
            if (EMPTY_VALUE === $indexElement->date) {
55
                $contentObject->date = $indexElement->date;
56
                $contentObject->timestamp = EMPTY_VALUE;
57
            } else {
58
                $dt = new \DateTime($indexElement->date);
59
                $contentObject->date = $dt->format($this->config->getString(Config::KEY_POST_DATE_FMT));
60
                $contentObject->timestamp = $dt->format(DateTimeInterface::W3C);
61
            }
62
        }
63
        $contentObject->listing = [];
64
        $contentObject->site = $this->getSiteObject();
65
        return $contentObject;
66
    }
67
68
    /**
69
     * Create the site object.
70
     * @return \stdClass
71
     */
72
    private function getSiteObject(): \stdClass {
73
        static $site = null;
74
        if (empty($site)) {
75
            $site = new \stdClass();
76
            $site->url = $this->config->getString(Config::KEY_SITE_URL);
77
            $site->name = $this->config->getString(Config::KEY_SITE_NAME);
78
            $site->title = $this->config->getString(Config::KEY_SITE_TITLE);
79
            $site->description = $this->config->getString(Config::KEY_SITE_DESCRIPTION);
80
            $site->tagline = $this->config->getString(Config::KEY_SITE_TAGLINE);
81
            $site->copyright = $this->config->getString(Config::KEY_SITE_COPYRIGHT);
82
            $site->language = $this->config->getString(Config::KEY_LANG);
83
            $site->theme = $this->config->getString(Config::KEY_THEME_NAME);
84
            $site->tpl_engine = $this->config->getString(Config::KEY_TPL_ENGINE);
85
        }
86
        return $site;
87
    }
88
89
    private function loadDataFile(\stdClass $indexElement): \stdClass {
90
        if (!isset($indexElement->path) || empty($indexElement->path)) {
91
            throw new InvalidArgumentException("Object does not have 'path' property "./** @scrutinizer ignore-type */print_r($indexElement, true)); // @codeCoverageIgnore
92
        }
93
        if (($data = \file_get_contents($indexElement->path)) === false) {
94
            throw new InternalException("file_get_contents() failed opening [$indexElement->path]"); // @codeCoverageIgnore
95
        }
96
        if (($contentObject = \json_decode($data)) === null) {
97
            $path = $indexElement->path;
98
            throw new InternalException("json_decode returned null decoding [$data] from [$path]"); // @codeCoverageIgnore
99
        }
100
        return $contentObject;
101
    }
102
}
103