Completed
Pull Request — master (#39)
by Sebastian
11:45
created

CiteProc::init()   A

Complexity

Conditions 1
Paths 1

Size

Total Lines 8
Code Lines 6

Duplication

Lines 0
Ratio 0 %

Importance

Changes 0
Metric Value
cc 1
eloc 6
nc 1
nop 1
dl 0
loc 8
rs 9.4285
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;
11
12
use Seboettg\CiteProc\Data\DataList;
13
use Seboettg\CiteProc\Exception\CiteProcException;
14
use Seboettg\CiteProc\Root\Info;
15
use Seboettg\CiteProc\Style\Bibliography;
16
use Seboettg\CiteProc\Style\Citation;
17
use Seboettg\CiteProc\Style\Macro;
18
use Seboettg\CiteProc\Style\Options\GlobalOptions;
19
use Seboettg\CiteProc\Root\Root;
20
use Seboettg\CiteProc\Styles\Css\CssStyle;
21
use Seboettg\Collection\ArrayList;
22
23
24
/**
25
 * Class CiteProc
26
 * @package Seboettg\CiteProc
27
 *
28
 * @author Sebastian Böttger <[email protected]>
29
 */
30
class CiteProc
31
{
32
33
    /**
34
     * @var Context
35
     */
36
    private static $context;
37
38
39
    /**
40
     * @return Context
41
     */
42
    public static function getContext()
43
    {
44
        return self::$context;
45
    }
46
47
    /**
48
     * @param Context $context
49
     */
50
    public static function setContext($context)
51
    {
52
        self::$context = $context;
53
    }
54
55
    private $lang;
56
57
    /**
58
     * @var string
59
     */
60
    private $styleSheet;
61
62
    /**
63
     * @var \SimpleXMLElement
64
     */
65
    private $styleSheetXml;
66
67
    /**
68
     * CiteProc constructor.
69
     * @param string $styleSheet xml formatted csl stylesheet
70
     */
71
    public function __construct($styleSheet, $lang = "en-US")
72
    {
73
        $this->styleSheet = $styleSheet;
74
        $this->lang = $lang;
75
    }
76
77
    public function __destruct()
78
    {
79
        self::$context = null;
80
    }
81
82
    /**
83
     * @param \SimpleXMLElement $style
84
     */
85
    private function parse(\SimpleXMLElement $style)
86
    {
87
        $root = new Root();
88
        $root->initInheritableNameAttributes($style);
89
        self::$context->setRoot($root);
90
        $globalOptions = new GlobalOptions($style);
91
        self::$context->setGlobalOptions($globalOptions);
92
93
        /** @var \SimpleXMLElement $node */
94
        foreach ($style as $node) {
95
            $name = $node->getName();
96
            switch ($name) {
97
                case 'info':
98
                    self::$context->setInfo(new Info($node));
99
                    break;
100
                case 'locale':
101
                    self::$context->getLocale()->addXml($node);
102
                    break;
103
                case 'macro':
104
                    $macro = new Macro($node, $root);
0 ignored issues
show
Documentation introduced by
$root is of type object<Seboettg\CiteProc\Root\Root>, but the function expects a object<Seboettg\CiteProc\Style\Root>.

It seems like the type of the argument is not accepted by the function/method which you are calling.

In some cases, in particular if PHP’s automatic type-juggling kicks in this might be fine. In other cases, however this might be a bug.

We suggest to add an explicit type cast like in the following example:

function acceptsInteger($int) { }

$x = '123'; // string "123"

// Instead of
acceptsInteger($x);

// we recommend to use
acceptsInteger((integer) $x);
Loading history...
105
                    self::$context->addMacro($macro->getName(), $macro);
106
                    break;
107
                case 'bibliography':
108
                    $bibliography = new Bibliography($node, $root);
0 ignored issues
show
Documentation introduced by
$root is of type object<Seboettg\CiteProc\Root\Root>, but the function expects a object<Seboettg\CiteProc\Style\Root>.

It seems like the type of the argument is not accepted by the function/method which you are calling.

In some cases, in particular if PHP’s automatic type-juggling kicks in this might be fine. In other cases, however this might be a bug.

We suggest to add an explicit type cast like in the following example:

function acceptsInteger($int) { }

$x = '123'; // string "123"

// Instead of
acceptsInteger($x);

// we recommend to use
acceptsInteger((integer) $x);
Loading history...
109
                    self::$context->setBibliography($bibliography);
110
                    break;
111
                case 'citation':
112
                    $citation = new Citation($node, $root);
113
                    self::$context->setCitation($citation);
114
                    break;
115
            }
116
        }
117
    }
118
119
    /**
120
     * @param DataList $data
121
     * @return string
0 ignored issues
show
Documentation introduced by
Should the return type not be string|array?

This check compares the return type specified in the @return annotation of a function or method doc comment with the types returned by the function and raises an issue if they mismatch.

Loading history...
122
     */
123
    protected function bibliography($data)
124
    {
125
126
        return self::$context->getBibliography()->render($data);
127
    }
128
129
    /**
130
     * @param DataList $data
131
     * @param ArrayList $citationItems
132
     * @return string
0 ignored issues
show
Documentation introduced by
Should the return type not be string|array?

This check compares the return type specified in the @return annotation of a function or method doc comment with the types returned by the function and raises an issue if they mismatch.

Loading history...
133
     */
134
    protected function citation($data, $citationItems)
135
    {
136
        return self::$context->getCitation()->render($data, $citationItems);
137
    }
138
139
    /**
140
     * @param array|DataList $data
141
     * @param string $mode (citation|bibliography)
142
     * @param array $citationItems
143
     * @return string|array
144
     * @throws CiteProcException
145
     */
146
    public function render($data, $mode = "bibliography", $citationItems = [], $citationAsArray = false)
147
    {
148
149
        if (!in_array($mode, ['citation', 'bibliography'])) {
150
            throw new \InvalidArgumentException("\"$mode\" is not a valid mode.");
151
        }
152
153
        $this->init($citationAsArray); //initialize
154
155
        $res = "";
156
157
        if (is_array($data)) {
158
            $data = new DataList($data);
159
        } else if (!($data instanceof DataList)) {
160
            throw new CiteProcException('No valid format for variable data. Either DataList or array expected');
161
        }
162
163
164
165
        switch ($mode) {
166
            case 'bibliography':
167
                self::$context->setMode($mode);
168
                // set CitationItems to Context
169
                self::getContext()->setCitationItems($data);
170
                $res = $this->bibliography($data);
171
                break;
172
            case 'citation':
173
                if (is_array($citationItems)) {
174
                    $citationItems = new ArrayList($citationItems);
175
                } else if (!($citationItems instanceof ArrayList)) {
176
                    throw new CiteProcException('No valid format for variable `citationItems`, ArrayList expected.');
177
                }
178
                self::$context->setMode($mode);
179
                // set CitationItems to Context
180
                //self::getContext()->setCitationItems($data); will now set in Layout
0 ignored issues
show
Unused Code Comprehensibility introduced by
43% 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...
181
                $res = $this->citation($data, $citationItems);
182
        }
183
        self::setContext(null);
0 ignored issues
show
Documentation introduced by
null is of type null, but the function expects a object<Seboettg\CiteProc\Context>.

It seems like the type of the argument is not accepted by the function/method which you are calling.

In some cases, in particular if PHP’s automatic type-juggling kicks in this might be fine. In other cases, however this might be a bug.

We suggest to add an explicit type cast like in the following example:

function acceptsInteger($int) { }

$x = '123'; // string "123"

// Instead of
acceptsInteger($x);

// we recommend to use
acceptsInteger((integer) $x);
Loading history...
184
185
        return $res;
186
    }
187
188
    /**
189
     * initializes CiteProc and start parsing XML stylesheet
190
     */
191
    public function init($citationAsArray = false)
192
    {
193
        self::$context = new Context($this);
194
        self::$context->setLocale(new Locale\Locale($this->lang)); //init locale
195
        self::$context->setCitationsAsArray($citationAsArray);
196
        $this->styleSheetXml = new \SimpleXMLElement($this->styleSheet);
197
        $this->parse($this->styleSheetXml);
198
    }
199
200
    /**
201
     * @return string
202
     */
203
    public function renderCssStyles()
204
    {
205
        if (self::getContext() === null) {
206
            $this->init();
207
        }
208
209
        if (self::getContext()->getCssStyle() == null) {
210
            $cssStyle = new CssStyle(self::getContext()->getBibliographySpecificOptions());
211
            self::getContext()->setCssStyle($cssStyle);
212
        }
213
214
        return self::getContext()->getCssStyle()->render();
215
    }
216
}