Issues (155)

src/CitationReferencePositionJournal.php (3 issues)

Labels
1
<?php
2
3
namespace SCI;
4
5
use Onoi\Cache\Cache;
6
use SMW\DIWikiPage;
0 ignored issues
show
The type SMW\DIWikiPage was not found. Maybe you did not declare it correctly or list all dependencies?

The issue could also be caused by a filter entry in the build configuration. If the path has been excluded in your configuration, e.g. excluded_paths: ["lib/*"], you can move it to the dependency path list as follows:

filter:
    dependency_paths: ["lib/*"]

For further information see https://scrutinizer-ci.com/docs/tools/php/php-scrutinizer/#list-dependency-paths

Loading history...
7
use SMW\DIProperty;
0 ignored issues
show
The type SMW\DIProperty was not found. Maybe you did not declare it correctly or list all dependencies?

The issue could also be caused by a filter entry in the build configuration. If the path has been excluded in your configuration, e.g. excluded_paths: ["lib/*"], you can move it to the dependency path list as follows:

filter:
    dependency_paths: ["lib/*"]

For further information see https://scrutinizer-ci.com/docs/tools/php/php-scrutinizer/#list-dependency-paths

Loading history...
8
use SMW\SemanticData;
0 ignored issues
show
The type SMW\SemanticData was not found. Maybe you did not declare it correctly or list all dependencies?

The issue could also be caused by a filter entry in the build configuration. If the path has been excluded in your configuration, e.g. excluded_paths: ["lib/*"], you can move it to the dependency path list as follows:

filter:
    dependency_paths: ["lib/*"]

For further information see https://scrutinizer-ci.com/docs/tools/php/php-scrutinizer/#list-dependency-paths

Loading history...
9
10
/**
11
 * @license GNU GPL v2+
12
 * @since 1.0
13
 *
14
 * @author mwjames
15
 */
16
class CitationReferencePositionJournal {
17
18
	/**
19
	 * @var Cache
20
	 */
21
	private $cache = null;
22
23
	/**
24
	 * @var CacheKeyProvider
25
	 */
26
	private $cacheKeyProvider;
27
28
	/**
29
	 * @var array
30
	 */
31
	private static $citationReferenceJournal = [];
32
33
	/**
34
	 * @since 1.0
35
	 *
36
	 * @param Cache $cache
37
	 * @param CacheKeyProvider $cacheKeyProvider
38
	 */
39 18
	public function __construct( Cache $cache, CacheKeyProvider $cacheKeyProvider ) {
40 18
		$this->cache = $cache;
41 18
		$this->cacheKeyProvider = $cacheKeyProvider;
42 18
	}
43
44
	/**
45
	 * @since 1.0
46
	 *
47
	 * @param DIWikiPage $subject
48
	 *
49
	 * @return boolean
50
	 */
51 14
	public function hasCitationReference( SemanticData $semanticData ) {
52 14
		return $semanticData->getPropertyValues( new DIProperty( PropertyRegistry::SCI_CITE_REFERENCE ) ) !== [];
53
	}
54
55
	/**
56
	 * @since 1.0
57
	 *
58
	 * @param  DIWikiPage $subject
59
	 *
60
	 * @return array|null
61
	 */
62 9
	public function getJournalBySubject( DIWikiPage $subject ) {
63 9
		return $this->hasJournalForHash( $subject->getHash() ) ? self::$citationReferenceJournal[$subject->getHash()] : null;
64
	}
65
66
	/**
67
	 * @note Build a journal from unbound references (loose from the subject invoked
68
	 * citation references), the position isn't important because those will not
69
	 * be linked to any CiteRef anchors.
70
	 *
71
	 * @since 1.0
72
	 *
73
	 * @param  array $referenceList
74
	 *
75
	 * @return array|null
76
	 */
77 3
	public function buildJournalForUnboundReferenceList( array $referenceList ) {
78
79 3
		if ( $referenceList === [] ) {
80 1
			return null;
81
		}
82
83
		$journal = [
84 3
			'total' => 0,
85
			'reference-list' => [],
86
			'reference-pos'  => []
87
		];
88
89 3
		$journal['total'] = count( $referenceList );
90
91 3
		foreach ( $referenceList as $reference ) {
92 3
			$journal['reference-pos'][$reference] = [];
93 3
			$journal['reference-list'][$reference] = $reference;
94
		}
95
96 3
		return $journal;
97
	}
98
99
	/**
100
	 * @since 1.0
101
	 *
102
	 * @param DIWikiPage|null $subject
103
	 * @param string $reference
104
	 *
105
	 * @return string|null
106
	 */
107 7
	public function findLastReferencePositionEntryFor( DIWikiPage $subject = null, $reference ) {
108
109 7
		if ( $subject === null ) {
110
			return;
111
		}
112
113 7
		$referenceHash = md5( $reference );
114 7
		$hash = $subject->getHash();
115
116
		// Tracks the current parser run invoked by the InTextAnnotationParser
117 7
		$uniqid = $subject->getContextReference();
118
119 7
		if ( $this->hasJournalForHash( $hash ) &&
120 7
			self::$citationReferenceJournal[$hash]['uniqid'] === $uniqid &&
121 7
			isset( self::$citationReferenceJournal[$hash]['reference-pos'][$referenceHash] ) ) {
122 7
			return end( self::$citationReferenceJournal[$hash]['reference-pos'][$referenceHash] );
123
		}
124
125
		return null;
126
	}
127
128
	/**
129
	 * @since 1.0
130
	 *
131
	 * @param DIWikiPage|null $subject
132
	 * @param string $reference
133
	 */
134 9
	public function addJournalEntryFor( DIWikiPage $subject = null, $reference ) {
135
136 9
		if ( $subject === null ) {
137 1
			return;
138
		}
139
140 8
		$referenceHash = md5( $reference );
141 8
		$hash = $subject->getHash();
142
143
		// Tracks the current parser run invoked by the InTextAnnotationParser
144 8
		$uniqid = $subject->getContextReference();
145
146 8
		if ( !$this->hasJournalForHash( $hash ) || self::$citationReferenceJournal[$hash]['uniqid'] !== $uniqid ) {
147
			$journal = [
148 8
				'uniqid'     => $uniqid,
149 8
				'total'      => 0,
150
				'reference-list' => [],
151
				'reference-pos'  => []
152
			];
153
		} else {
154 6
			$journal = self::$citationReferenceJournal[$hash];
155
		}
156
157
		// Caching the hash -> human readable key so that it can be reused
158
		// without any additional DB/Store access by the ReferenceListOutputRenderer
159 8
		$journal['reference-list'][$referenceHash] = $reference;
160
161
		// New reference, increase the total of existing citations for this
162
		// subject and set the position level to 'a'
163 8
		if ( !isset( $journal['reference-pos'][$referenceHash] ) || $journal['reference-pos'][$referenceHash] === [] ) {
164 8
			$journal['total']++;
165 8
			$journal['reference-pos'][$referenceHash][] = $journal['total'] . '-' . 'a';
166
		} else {
167
			// Found a citation with the same reference but for a different in-text
168
			// location.
169
			//
170
			// Increment the minor to a -> b -> c in order to create a map of
171
			// locations like 1-a, 1-b, 2-a etc.
172
			//
173
			// The exact position is specified by something like
174
			// like 57d0dc056f9e5d5c6cfc77fc27091f60-1-a and to be used within
175
			// html as link anchor
176 6
			list( $major, $minor ) = explode( '-', end( $journal['reference-pos'][$referenceHash] ) );
177 6
			$journal['reference-pos'][$referenceHash][] = $major . '-' . ++$minor;
178
		}
179
180 8
	 	self::$citationReferenceJournal[$hash] = $journal;
181
182
	 	// Safeguard against a repeated call to the hashlist for when the static
183
	 	// cache is empty
184 8
		$this->cache->save(
185 8
			$this->cacheKeyProvider->getCacheKeyForCitationReference( $hash ),
186 8
			self::$citationReferenceJournal
187
		);
188 8
	}
189
190 10
	private function hasJournalForHash( $hash ) {
191
192 10
		if ( self::$citationReferenceJournal === [] ) {
193 1
			self::$citationReferenceJournal = $this->cache->fetch(
194 1
				$this->cacheKeyProvider->getCacheKeyForCitationReference( $hash )
195
			);
196
		}
197
198 10
		return isset( self::$citationReferenceJournal[$hash] );
199
	}
200
201
}
202