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