Completed
Push — master ( eb64ee...e3cfef )
by WEBEWEB
02:08
created

QuoteProvider::getFilename()   A

Complexity

Conditions 1
Paths 1

Size

Total Lines 3

Duplication

Lines 0
Ratio 0 %

Importance

Changes 0
Metric Value
dl 0
loc 3
rs 10
c 0
b 0
f 0
cc 1
nc 1
nop 0
1
<?php
2
3
/*
4
 * This file is part of the core-bundle package.
5
 *
6
 * (c) 2019 WEBEWEB
7
 *
8
 * For the full copyright and license information, please view the LICENSE
9
 * file that was distributed with this source code.
10
 */
11
12
namespace WBW\Bundle\CoreBundle\Quote;
13
14
use DateTime;
15
use Symfony\Component\Filesystem\Exception\FileNotFoundException;
16
use Symfony\Component\Yaml\Yaml;
17
use WBW\Bundle\CoreBundle\Provider\QuoteProviderInterface;
18
use WBW\Library\Core\Argument\ArrayHelper;
19
20
/**
21
 * Quote provider.
22
 *
23
 * @author webeweb <https://github.com/webeweb/>
24
 * @package WBW\Bundle\CoreBundle\Quote
25
 */
26
class QuoteProvider implements QuoteProviderInterface {
27
28
    /**
29
     * Filename.
30
     *
31
     * @var string
32
     */
33
    private $filename;
34
35
    /**
36
     * Quotes.
37
     *
38
     * @var QuoteInterface[]
39
     */
40
    private $quotes;
41
42
    /**
43
     * Constructor.
44
     *
45
     * @param string $filename The filename.
46
     * @throws FileNotFoundException Throws a file not found exception.
47
     */
48
    public function __construct($filename) {
49
        $this->setFilename($filename);
50
        $this->setQuotes([]);
51
    }
52
53
    /**
54
     *{@inheritDoc}
55
     */
56
    public function getAuthors() {
57
58
        $authors = [];
59
60
        foreach ($this->quotes as $current) {
61
            if (true === in_array($current->getAuthor(), $authors)) {
62
                continue;
63
            }
64
            $authors[] = $current->getAuthor();
65
        }
66
67
        asort($authors);
68
69
        return $authors;
70
    }
71
72
    /**
73
     * {@inheritDoc}
74
     */
75
    public function getDomain() {
76
        return basename($this->getFilename(), ".yml");
77
    }
78
79
    /**
80
     * Get the filename.
81
     *
82
     * @return string Returns the filename.
83
     */
84
    public function getFilename() {
85
        return $this->filename;
86
    }
87
88
    /**
89
     * {@onheritDoc}
90
     */
91
    public function getQuotes() {
92
        return $this->quotes;
0 ignored issues
show
Bug Best Practice introduced by
The return type of return $this->quotes; (WBW\Bundle\CoreBundle\Quote\QuoteInterface[]) is incompatible with the return type declared by the interface WBW\Bundle\CoreBundle\Pr...derInterface::getQuotes of type WBW\Bundle\CoreBundle\Provider\QuoteInterface[].

If you return a value from a function or method, it should be a sub-type of the type that is given by the parent type f.e. an interface, or abstract method. This is more formally defined by the Lizkov substitution principle, and guarantees that classes that depend on the parent type can use any instance of a child type interchangably. This principle also belongs to the SOLID principles for object oriented design.

Let’s take a look at an example:

class Author {
    private $name;

    public function __construct($name) {
        $this->name = $name;
    }

    public function getName() {
        return $this->name;
    }
}

abstract class Post {
    public function getAuthor() {
        return 'Johannes';
    }
}

class BlogPost extends Post {
    public function getAuthor() {
        return new Author('Johannes');
    }
}

class ForumPost extends Post { /* ... */ }

function my_function(Post $post) {
    echo strtoupper($post->getAuthor());
}

Our function my_function expects a Post object, and outputs the author of the post. The base class Post returns a simple string and outputting a simple string will work just fine. However, the child class BlogPost which is a sub-type of Post instead decided to return an object, and is therefore violating the SOLID principles. If a BlogPost were passed to my_function, PHP would not complain, but ultimately fail when executing the strtoupper call in its body.

Loading history...
93
    }
94
95
    /**
96
     * {@inheritDoc}
97
     */
98
    public function init() {
99
100
        $fileContent = file_get_contents($this->filename);
101
102
        $yamlContent = Yaml::parse($fileContent);
103
104
        foreach ($yamlContent as $k => $v) {
105
106
            // Force year to manage the leap years.
107
            $date = DateTime::createFromFormat("!Y.m.d", "2016." . $k);
108
109
            $model = new Quote();
110
            $model->setDate(false === $date ? null : $date);
111
            $model->setAuthor(ArrayHelper::get($v, "author"));
112
            $model->setContent(ArrayHelper::get($v, "content"));
113
114
            $this->quotes[$k] = $model;
115
        }
116
    }
117
118
    /**
119
     * Set the filename.
120
     *
121
     * @param string $filename The filename.
122
     * @return QuoteProvider Returns this quote provider.
123
     * @throws FileNotFoundException Throws a file not found exception.
124
     */
125
    protected function setFilename($filename) {
126
        if (false === realpath($filename)) {
127
            throw new FileNotFoundException(sprintf("The file \"%s\" was not found", $filename));
128
        }
129
        $this->filename = realpath($filename);
130
        return $this;
131
    }
132
133
    /**
134
     * Set the quotes.
135
     *
136
     * @param QuoteInterface[] $quotes The quotes.
137
     * @return QuoteProvider Returns this quote provider.
138
     */
139
    protected function setQuotes(array $quotes) {
140
        $this->quotes = $quotes;
141
        return $this;
142
    }
143
}
144