Code Coverage
 
Lines
Functions and Methods
Classes and Traits
Total
100.00% covered (success)
100.00%
37 / 37
100.00% covered (success)
100.00%
9 / 9
CRAP
100.00% covered (success)
100.00%
1 / 1
ReferencesData
100.00% covered (success)
100.00%
37 / 37
100.00% covered (success)
100.00%
9 / 9
16
100.00% covered (success)
100.00%
1 / 1
 inReferencesContent
100.00% covered (success)
100.00%
1 / 1
100.00% covered (success)
100.00%
1 / 1
1
 inEmbeddedContent
100.00% covered (success)
100.00%
3 / 3
100.00% covered (success)
100.00%
1 / 1
2
 pushEmbeddedContentFlag
100.00% covered (success)
100.00%
1 / 1
100.00% covered (success)
100.00%
1 / 1
1
 popEmbeddedContentFlag
100.00% covered (success)
100.00%
1 / 1
100.00% covered (success)
100.00%
1 / 1
1
 getRefGroup
100.00% covered (success)
100.00%
3 / 3
100.00% covered (success)
100.00%
1 / 1
2
 removeRefGroup
100.00% covered (success)
100.00%
1 / 1
100.00% covered (success)
100.00%
1 / 1
1
 normalizeKey
100.00% covered (success)
100.00%
3 / 3
100.00% covered (success)
100.00%
1 / 1
1
 add
100.00% covered (success)
100.00%
23 / 23
100.00% covered (success)
100.00%
1 / 1
6
 getRefGroups
100.00% covered (success)
100.00%
1 / 1
100.00% covered (success)
100.00%
1 / 1
1
1<?php
2declare( strict_types = 1 );
3
4namespace Cite\Parsoid;
5
6use Wikimedia\Parsoid\Core\Sanitizer;
7use Wikimedia\Parsoid\Ext\ParsoidExtensionAPI;
8use Wikimedia\Parsoid\NodeData\DataMwError;
9
10/**
11 * @license GPL-2.0-or-later
12 */
13class ReferencesData {
14
15    private int $index = 0;
16    /** @var array<string,RefGroup> indexed by group name */
17    private array $refGroups = [];
18    /** @var array<string,list<DataMwError>> */
19    public array $embeddedErrors = [];
20    /** @var string[] */
21    private array $inEmbeddedContent = [];
22    public string $referencesGroup = '';
23
24    public function inReferencesContent(): bool {
25        return $this->inEmbeddedContent( 'references' );
26    }
27
28    public function inEmbeddedContent( ?string $needle = null ): bool {
29        if ( $needle ) {
30            return in_array( $needle, $this->inEmbeddedContent, true );
31        } else {
32            return $this->inEmbeddedContent !== [];
33        }
34    }
35
36    public function pushEmbeddedContentFlag( string $needle = 'embed' ): void {
37        array_unshift( $this->inEmbeddedContent, $needle );
38    }
39
40    public function popEmbeddedContentFlag() {
41        array_shift( $this->inEmbeddedContent );
42    }
43
44    public function getRefGroup(
45        string $groupName, bool $allocIfMissing = false
46    ): ?RefGroup {
47        if ( $allocIfMissing ) {
48            $this->refGroups[$groupName] ??= new RefGroup( $groupName );
49        }
50        return $this->refGroups[$groupName] ?? null;
51    }
52
53    public function removeRefGroup( string $groupName ): void {
54        // '' is a valid group (the default group)
55        unset( $this->refGroups[$groupName] );
56    }
57
58    /**
59     * Normalizes and sanitizes a reference key
60     *
61     * @param string $key
62     * @return string
63     */
64    private function normalizeKey( string $key ): string {
65        $ret = Sanitizer::escapeIdForLink( $key );
66        $ret = preg_replace( '/[_\s]+/u', '_', $ret );
67        return $ret;
68    }
69
70    public function add(
71        ParsoidExtensionAPI $extApi, string $groupName, string $refName, ?string $extendsRef, string $refDir
72    ): RefGroupItem {
73        $group = $this->getRefGroup( $groupName, true );
74        $hasRefName = $refName !== '';
75
76        // The ids produced Cite.php have some particulars:
77        // Simple refs get 'cite_ref-' + index
78        // Refs with names get 'cite_ref-' + name + '_' + index + (backlink num || 0)
79        // Notes (references) whose ref doesn't have a name are 'cite_note-' + index
80        // Notes whose ref has a name are 'cite_note-' + name + '-' + index
81        $n = $this->index;
82        $refKey = strval( 1 + $n );
83
84        $refNameSanitized = $this->normalizeKey( $refName );
85
86        $refIdBase = 'cite_ref-' . ( $hasRefName ? $refNameSanitized . '_' . $refKey : $refKey );
87        $noteId = 'cite_note-' . ( $hasRefName ? $refNameSanitized . '-' . $refKey : $refKey );
88
89        // bump index
90        $this->index++;
91
92        $ref = new RefGroupItem();
93        $ref->dir = $refDir;
94        $ref->group = $group->name;
95        $ref->groupIndex = count( $group->refs ) + 1;
96        if ( $extendsRef ) {
97            $ref->extendsRef = $extendsRef;
98        }
99        $ref->index = $n;
100        $ref->key = $refIdBase;
101        $ref->id = $hasRefName ? $refIdBase . '-0' : $refIdBase;
102        $ref->name = $refName;
103        $ref->target = $noteId;
104
105        $group->refs[] = $ref;
106
107        if ( $hasRefName ) {
108            $group->indexByName[$refName] = $ref;
109        }
110
111        return $ref;
112    }
113
114    /**
115     * @return RefGroup[]
116     */
117    public function getRefGroups(): array {
118        return $this->refGroups;
119    }
120}