Completed
Push — master ( 5a7e4d...40d001 )
by Sebastian
04:05
created

Text::__construct()   A

Complexity

Conditions 4
Paths 5

Size

Total Lines 18
Code Lines 13

Duplication

Lines 0
Ratio 0 %

Importance

Changes 0
Metric Value
cc 4
eloc 13
nc 5
nop 1
dl 0
loc 18
rs 9.2
c 0
b 0
f 0
1
<?php
2
/*
3
 * citeproc-php
4
 *
5
 * @link        http://github.com/seboettg/citeproc-php for the source repository
6
 * @copyright   Copyright (c) 2016 Sebastian Böttger.
7
 * @license     https://opensource.org/licenses/MIT
8
 */
9
10
namespace Seboettg\CiteProc\Rendering;
11
12
use Seboettg\CiteProc\CiteProc;
13
use Seboettg\CiteProc\Exception\CiteProcException;
14
use Seboettg\CiteProc\Styles\AffixesTrait;
15
use Seboettg\CiteProc\Styles\ConsecutivePunctuationCharacterTrait;
16
use Seboettg\CiteProc\Styles\DisplayTrait;
17
use Seboettg\CiteProc\Styles\FormattingTrait;
18
use Seboettg\CiteProc\Styles\QuotesTrait;
19
use Seboettg\CiteProc\Styles\TextCaseTrait;
20
use Seboettg\CiteProc\Util\NumberHelper;
21
use Seboettg\CiteProc\Util\PageHelper;
22
use Seboettg\CiteProc\Util\StringHelper;
23
24
25
/**
26
 * Class Term
27
 * @package Seboettg\CiteProc\Node\Style
28
 *
29
 * @author Sebastian Böttger <[email protected]>
30
 */
31
class Text implements Rendering, RendersEmptyVariables
32
{
33
    use FormattingTrait,
34
        AffixesTrait,
35
        TextCaseTrait,
36
        DisplayTrait,
37
        ConsecutivePunctuationCharacterTrait,
38
        QuotesTrait,
39
        RendersEmptyVariablesTrait;
40
41
    /**
42
     * @var string
43
     */
44
    private $toRenderType;
45
46
    /**
47
     * @var string
48
     */
49
    private $toRenderTypeValue;
50
51
    /**
52
     * @var string
53
     */
54
    private $form = "long";
55
56
    /**
57
     * Text constructor.
58
     * @param \SimpleXMLElement $node
59
     */
60
    public function __construct(\SimpleXMLElement $node)
61
    {
62
        foreach ($node->attributes() as $attribute) {
63
            $name = $attribute->getName();
64
            if (in_array($name, ['value', 'variable', 'macro', 'term'])) {
65
                $this->toRenderType = $name;
66
                $this->toRenderTypeValue = (string) $attribute;
67
            }
68
            if ($name === "form") {
69
                $this->form = (string) $attribute;
70
            }
71
        }
72
        $this->initFormattingAttributes($node);
73
        $this->initDisplayAttributes($node);
74
        $this->initTextCaseAttributes($node);
75
        $this->initAffixesAttributes($node);
76
        $this->initQuotesAttributes($node);
77
    }
78
79
    /**
80
     * @param \stdClass $data
81
     * @param int|null $citationNumber
82
     * @return string
83
     */
84
    public function render($data, $citationNumber = null)
85
    {
86
        $lang = (isset($data->language) && $data->language != 'en') ? $data->language : 'en';
87
88
        $renderedText = "";
89
        switch ($this->toRenderType) {
90
            case 'value':
91
                $renderedText = $this->applyTextCase($this->toRenderTypeValue, $lang);
92
                break;
93
            case 'variable':
94
                if ($this->toRenderTypeValue === "citation-number") {
95
                    $renderedText = $citationNumber + 1;
96
                    break;
97
                }
98
99
                if ($this->toRenderTypeValue === "page") {
100
                    $renderedText = $this->renderPage($data);
101
                    // for test sort_BibliographyCitationNumberDescending.json
102
                } else if ($this->toRenderTypeValue === "citation-number" && !is_null($citationNumber)) {
103
                    $renderedText = strval($citationNumber + 1);
104
                } else {
105
106
                    // check if there is an attribute with prefix short or long e.g. shortTitle or longAbstract
107
                    // test case group_ShortOutputOnly.json
108
                    if (in_array($this->form, ["short", "long"])) {
109
                        $attrWithPrefix = $this->form . ucfirst($this->toRenderTypeValue);
110
                        if (isset($data->{$attrWithPrefix}) && !empty($data->{$attrWithPrefix})) {
111
                            $renderedText = $this->applyTextCase($data->{$attrWithPrefix}, $lang);
112
                        }
113
                    }
114
                    if (!empty($data->{$this->toRenderTypeValue})) {
115
                        $renderedText = $this->applyTextCase(StringHelper::clearApostrophes($data->{$this->toRenderTypeValue}), $lang);
116
                    }
117
                }
118
                break;
119
            case 'macro':
120
                $macro = CiteProc::getContext()->getMacro($this->toRenderTypeValue);
121
                if (is_null($macro)) {
122
                    try {
123
                        throw new CiteProcException("Macro \"" . $this->toRenderTypeValue . "\" does not exist.");
124
                    } catch (CiteProcException $e) {
125
                        $renderedText = "";
126
                    }
127
                } else {
128
                    $renderedText = $macro->render($data);
129
                }
130
                break;
131
            case 'term':
132
                $term = CiteProc::getContext()->getLocale()->filter("terms", $this->toRenderTypeValue, $this->form)->single;
133
                $renderedText = !empty($term) ? $this->applyTextCase($term, $lang) : "";
134
        }
135
        if (!empty($renderedText)) {
136
            //$renderedText = $this->applyTextCase($renderedText);
0 ignored issues
show
Unused Code Comprehensibility introduced by
64% of this comment could be valid code. Did you maybe forget this after debugging?

Sometimes obsolete code just ends up commented out instead of removed. In this case it is better to remove the code once you have checked you do not need it.

The code might also have been commented out for debugging purposes. In this case it is vital that someone uncomments it again or your project may behave in very unexpected ways in production.

This check looks for comments that seem to be mostly valid code and reports them.

Loading history...
137
            $text = $this->format($renderedText);
138
            $res = $this->addAffixes($text, $this->quotes);
0 ignored issues
show
Unused Code introduced by
The call to Text::addAffixes() has too many arguments starting with $this->quotes.

This check compares calls to functions or methods with their respective definitions. If the call has more arguments than are defined, it raises an issue.

If a function is defined several times with a different number of parameters, the check may pick up the wrong definition and report false positives. One codebase where this has been known to happen is Wordpress.

In this case you can add the @ignore PhpDoc annotation to the duplicate definition and it will be ignored.

Loading history...
139
            if (!empty($res)) {
140
                $res = $this->removeConsecutiveChars($res);
141
            }
142
            $res = $this->addSurroundingQuotes($res);
143
            return $this->wrapDisplayBlock($res);
144
        }
145
        return "";
146
    }
147
148
    public function rendersMacro()
149
    {
150
        return $this->toRenderType === "macro";
151
    }
152
153
    /**
154
     * @return string
155
     */
156
    public function getSource()
157
    {
158
        return $this->toRenderType;
159
    }
160
161
    /**
162
     * @return string
163
     */
164
    public function getVariable()
165
    {
166
        return $this->toRenderTypeValue;
167
    }
168
169
    private function renderPage($data)
170
    {
171
        if (empty($data->page)) {
172
            return "";
173
        }
174
175
        if (preg_match(NumberHelper::PATTERN_COMMA_AMPERSAND_RANGE, $data->page)) {
176
            $data->page = $this->normalizeDateRange($data->page);
177
            $ranges = preg_split("/[-–]/", trim($data->page));
178
            if (!empty(CiteProc::getContext()->getGlobalOptions()->getPageRangeFormat())) {
179
                return PageHelper::processPageRangeFormats($ranges, CiteProc::getContext()->getGlobalOptions()->getPageRangeFormat());
180
            }
181
            list($from, $to) = $ranges;
182
            return "$from-$to";
183
        }
184
        return $data->page;
185
    }
186
187
    public function rendersEmptyVariables($data)
188
    {
189
        if($this->toRenderType === "variable" &&
190
            (!isset($data->{$this->toRenderTypeValue}) || empty($data->{$this->toRenderTypeValue}))) {
191
            return true;
192
        } else if ($this->toRenderType === "macro") {
193
            $macro = CiteProc::getContext()->getMacro($this->toRenderTypeValue);
194
            return !empty($macro) ? $macro->rendersEmptyVariables($data) : false;
195
        }
196
        return false;
197
    }
198
199
    private function normalizeDateRange($page)
200
    {
201
        if (preg_match("/^(\d+)--(\d+)$/", trim($page), $matches)) {
202
            return $matches[1]."-".$matches[2];
203
        }
204
        return $page;
205
    }
206
}