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 Exception; |
||||
13 | use InvalidArgumentException; |
||||
14 | use Seboettg\CiteProc\Data\DataList; |
||||
15 | use Seboettg\CiteProc\Exception\CiteProcException; |
||||
16 | use Seboettg\CiteProc\Root\Info; |
||||
17 | use Seboettg\CiteProc\Style\Bibliography; |
||||
18 | use Seboettg\CiteProc\Style\Citation; |
||||
19 | use Seboettg\CiteProc\Style\Macro; |
||||
20 | use Seboettg\CiteProc\Style\Options\GlobalOptions; |
||||
21 | use Seboettg\CiteProc\Root\Root; |
||||
22 | use Seboettg\CiteProc\Styles\Css\CssStyle; |
||||
23 | use Seboettg\CiteProc\Util\CiteProcHelper; |
||||
24 | use Seboettg\Collection\ArrayList; |
||||
25 | use Seboettg\Collection\Lists\ListInterface; |
||||
26 | use Seboettg\Collection\Map\MapInterface; |
||||
27 | use SimpleXMLElement; |
||||
28 | use function Seboettg\Collection\Lists\listOf; |
||||
29 | use function Seboettg\Collection\Map\emptyMap; |
||||
30 | |||||
31 | /** |
||||
32 | * Class CiteProc |
||||
33 | * @package Seboettg\CiteProc |
||||
34 | * |
||||
35 | * @author Sebastian Böttger <[email protected]> |
||||
36 | */ |
||||
37 | class CiteProc |
||||
38 | { |
||||
39 | |||||
40 | /** |
||||
41 | * @var Context |
||||
42 | */ |
||||
43 | private static $context; |
||||
44 | |||||
45 | |||||
46 | /** |
||||
47 | * @return Context |
||||
48 | */ |
||||
49 | public static function getContext() |
||||
50 | { |
||||
51 | return self::$context; |
||||
52 | } |
||||
53 | |||||
54 | /** |
||||
55 | * @param Context $context |
||||
56 | */ |
||||
57 | public static function setContext($context) |
||||
58 | { |
||||
59 | self::$context = $context; |
||||
60 | } |
||||
61 | |||||
62 | private $lang; |
||||
63 | |||||
64 | /** |
||||
65 | * @var string |
||||
66 | */ |
||||
67 | private $styleSheet; |
||||
68 | |||||
69 | /** |
||||
70 | * @var SimpleXMLElement |
||||
71 | */ |
||||
72 | private $styleSheetXml; |
||||
73 | |||||
74 | /** |
||||
75 | * @var array |
||||
76 | */ |
||||
77 | private $markupExtension; |
||||
78 | |||||
79 | /** |
||||
80 | * CiteProc constructor. |
||||
81 | * @param string $styleSheet xml formatted csl stylesheet |
||||
82 | * @param string $lang |
||||
83 | * @param array $markupExtension |
||||
84 | */ |
||||
85 | public function __construct($styleSheet, $lang = "en-US", $markupExtension = []) |
||||
86 | { |
||||
87 | $this->styleSheet = $styleSheet; |
||||
88 | $this->lang = $lang; |
||||
89 | $this->markupExtension = $markupExtension; |
||||
90 | } |
||||
91 | |||||
92 | public function __destruct() |
||||
93 | { |
||||
94 | self::$context = null; |
||||
95 | } |
||||
96 | |||||
97 | /** |
||||
98 | * @param SimpleXMLElement $style |
||||
99 | * @throws CiteProcException |
||||
100 | */ |
||||
101 | private function parse(SimpleXMLElement $style) |
||||
102 | { |
||||
103 | $root = new Root(); |
||||
104 | $root->initInheritableNameAttributes($style); |
||||
105 | self::$context->setRoot($root); |
||||
106 | $globalOptions = new GlobalOptions($style); |
||||
107 | self::$context->setGlobalOptions($globalOptions); |
||||
108 | |||||
109 | /** @var SimpleXMLElement $node */ |
||||
110 | foreach ($style as $node) { |
||||
111 | $name = $node->getName(); |
||||
0 ignored issues
–
show
|
|||||
112 | switch ($name) { |
||||
113 | case 'info': |
||||
114 | self::$context->setInfo(new Info($node)); |
||||
0 ignored issues
–
show
It seems like
$node can also be of type null ; however, parameter $node of Seboettg\CiteProc\Root\Info::__construct() does only seem to accept SimpleXMLElement , maybe add an additional type check?
(
Ignorable by Annotation
)
If this is a false-positive, you can also ignore this issue in your code via the
![]() |
|||||
115 | break; |
||||
116 | case 'locale': |
||||
117 | self::$context->getLocale()->addXml($node); |
||||
0 ignored issues
–
show
It seems like
$node can also be of type null ; however, parameter $xml of Seboettg\CiteProc\Locale\Locale::addXml() does only seem to accept SimpleXMLElement , maybe add an additional type check?
(
Ignorable by Annotation
)
If this is a false-positive, you can also ignore this issue in your code via the
![]() |
|||||
118 | break; |
||||
119 | case 'macro': |
||||
120 | $macro = new Macro($node, $root); |
||||
0 ignored issues
–
show
It seems like
$node can also be of type null ; however, parameter $node of Seboettg\CiteProc\Style\Macro::__construct() does only seem to accept SimpleXMLElement , maybe add an additional type check?
(
Ignorable by Annotation
)
If this is a false-positive, you can also ignore this issue in your code via the
![]() |
|||||
121 | self::$context->addMacro($macro->getName(), $macro); |
||||
122 | break; |
||||
123 | case 'bibliography': |
||||
124 | $bibliography = new Bibliography($node, $root); |
||||
0 ignored issues
–
show
It seems like
$node can also be of type null ; however, parameter $node of Seboettg\CiteProc\Style\...iography::__construct() does only seem to accept SimpleXMLElement , maybe add an additional type check?
(
Ignorable by Annotation
)
If this is a false-positive, you can also ignore this issue in your code via the
![]() |
|||||
125 | self::$context->setBibliography($bibliography); |
||||
126 | break; |
||||
127 | case 'citation': |
||||
128 | $citation = new Citation($node, $root); |
||||
0 ignored issues
–
show
It seems like
$node can also be of type null ; however, parameter $node of Seboettg\CiteProc\Style\Citation::__construct() does only seem to accept SimpleXMLElement , maybe add an additional type check?
(
Ignorable by Annotation
)
If this is a false-positive, you can also ignore this issue in your code via the
![]() |
|||||
129 | self::$context->setCitation($citation); |
||||
130 | break; |
||||
131 | } |
||||
132 | } |
||||
133 | } |
||||
134 | |||||
135 | /** |
||||
136 | * @param DataList $data |
||||
137 | * @return string |
||||
138 | */ |
||||
139 | protected function bibliography($data) |
||||
140 | { |
||||
141 | |||||
142 | return self::$context->getBibliography()->render($data); |
||||
143 | } |
||||
144 | |||||
145 | protected function citation(DataList $data, MapInterface $citationItems) |
||||
146 | { |
||||
147 | return self::$context->getCitation()->render($data, $citationItems); |
||||
148 | } |
||||
149 | |||||
150 | /** |
||||
151 | * @param array|DataList $data |
||||
152 | * @param string $mode (citation|bibliography) |
||||
153 | * @param array $citationItems |
||||
154 | * @param bool $citationAsArray |
||||
155 | * @return string|array |
||||
156 | * @throws CiteProcException |
||||
157 | */ |
||||
158 | public function render( |
||||
159 | $data_, |
||||
160 | string $mode = "bibliography", |
||||
161 | array $citationItems = [], |
||||
162 | bool $citationAsArray = false |
||||
163 | ) { |
||||
164 | if (is_array($data_)) { |
||||
165 | $data_ = CiteProcHelper::cloneArray($data_); |
||||
166 | } |
||||
167 | |||||
168 | if (!in_array($mode, ['citation', 'bibliography'])) { |
||||
169 | throw new InvalidArgumentException("\"$mode\" is not a valid mode."); |
||||
170 | } |
||||
171 | |||||
172 | $this->init($citationAsArray); //initialize |
||||
173 | |||||
174 | |||||
175 | if ($data_ instanceof Data\DataList) { |
||||
176 | $dataList = $data_; |
||||
177 | } else { |
||||
178 | if (is_array($data_)) { |
||||
179 | $dataList = new DataList(); |
||||
180 | $dataList->setArray($data_); |
||||
181 | } else { |
||||
182 | throw new CiteProcException('No valid format for variable data. Either DataList or array expected'); |
||||
183 | } |
||||
184 | } |
||||
185 | |||||
186 | switch ($mode) { |
||||
187 | case 'bibliography': |
||||
188 | self::$context->setMode($mode); |
||||
189 | // set CitationItems to Context |
||||
190 | self::getContext()->setCitationData($dataList); |
||||
191 | $res = $this->bibliography($dataList); |
||||
192 | break; |
||||
193 | case 'citation': |
||||
194 | if (is_array($citationItems)) { |
||||
0 ignored issues
–
show
|
|||||
195 | $citeItems = emptyMap(); |
||||
196 | $citationItems = listOfLists(...$citationItems); |
||||
197 | foreach ($data_ as $key => $value) { |
||||
198 | if (property_exists($value, "id") && $citationItems |
||||
199 | ->map(fn ($item) => $item->id)->contains($value->id)) { |
||||
200 | $k = $key + 1; |
||||
201 | $citeItems->put("$k", $value->id); |
||||
202 | } |
||||
203 | } |
||||
204 | } elseif (!($citationItems instanceof ListInterface)) { |
||||
205 | throw new CiteProcException('No valid format for variable `citationItems`, ArrayList expected.'); |
||||
206 | } |
||||
207 | self::$context->setMode($mode); |
||||
208 | // set CitationItems to Context |
||||
209 | self::getContext()->setCitationItems($citationItems); |
||||
210 | $res = $this->citation($dataList, $citeItems); |
||||
0 ignored issues
–
show
Comprehensibility
Best Practice
introduced
by
|
|||||
211 | break; |
||||
212 | default: |
||||
213 | throw new CiteProcException("Invalid mode $mode"); |
||||
214 | } |
||||
215 | self::setContext(null); |
||||
216 | |||||
217 | return $res; |
||||
218 | } |
||||
219 | |||||
220 | /** |
||||
221 | * initializes CiteProc and start parsing XML stylesheet |
||||
222 | * @param bool $citationAsArray |
||||
223 | * @throws CiteProcException |
||||
224 | * @throws Exception |
||||
225 | */ |
||||
226 | public function init(bool $citationAsArray = false) |
||||
227 | { |
||||
228 | self::$context = new Context(); |
||||
229 | self::$context->setLocale(new Locale\Locale($this->lang)); //init locale |
||||
230 | self::$context->setCitationsAsArray($citationAsArray); |
||||
231 | // set markup extensions |
||||
232 | self::$context->setMarkupExtension($this->markupExtension); |
||||
233 | $this->styleSheetXml = new SimpleXMLElement($this->styleSheet); |
||||
234 | $this->parse($this->styleSheetXml); |
||||
235 | } |
||||
236 | |||||
237 | /** |
||||
238 | * @return string |
||||
239 | * @throws CiteProcException |
||||
240 | */ |
||||
241 | public function renderCssStyles() |
||||
242 | { |
||||
243 | if (self::getContext() === null) { |
||||
244 | $this->init(); |
||||
245 | } |
||||
246 | |||||
247 | if (self::getContext()->getCssStyle() == null) { |
||||
248 | $cssStyle = new CssStyle(self::getContext()->getBibliographySpecificOptions()); |
||||
249 | self::getContext()->setCssStyle($cssStyle); |
||||
250 | } |
||||
251 | |||||
252 | return self::getContext()->getCssStyle()->render(); |
||||
253 | } |
||||
254 | } |
||||
255 |
This check looks for calls to methods that do not seem to exist on a given type. It looks for the method on the type itself as well as in inherited classes or implemented interfaces.
This is most likely a typographical error or the method has been renamed.