Refactor Plausi from musdb to move the logic into this subrepository
See #948
This commit is contained in:
parent
f35115e38c
commit
863c3a3c93
21
README.md
21
README.md
@ -1,3 +1,22 @@
|
||||
# Quality Assessment Tools at museum-digital
|
||||
|
||||
The classes of this library provide tools to access the quality of museum object records and provide tips for improving it.
|
||||
The classes of this library provide tools to access the quality of museum object
|
||||
records and provide tips for improving it.
|
||||
|
||||
## Tools
|
||||
|
||||
- PuQI
|
||||
|
||||
PuQI (class `MDPuqi`) generates a score determining the quality of object metadata
|
||||
based on e.g. counting linked entries.
|
||||
|
||||
## Plausi
|
||||
|
||||
Plausi analyzes an object's linked events (e.g. production, use) and identifies
|
||||
logical inconsistencies.
|
||||
|
||||
## Publications
|
||||
|
||||
### PuQI
|
||||
|
||||
Rohde-Enslin, S. (2015). PuQI – A Smart Way to Create Better Data. Uncommon Culture, 6(2), 122-129. <https://uncommonculture.org/ojs/index.php/UC/article/view/6218>
|
||||
|
75
src/Checks/Plausi/MDEventCategory.php
Normal file
75
src/Checks/Plausi/MDEventCategory.php
Normal file
@ -0,0 +1,75 @@
|
||||
<?PHP
|
||||
/**
|
||||
* Represents a higher level category of event types.
|
||||
*
|
||||
* @author Joshua Ramon Enslin <joshua@museum-digital.de>
|
||||
*/
|
||||
declare(strict_types = 1);
|
||||
|
||||
/**
|
||||
* Represents a higher level category of event types.
|
||||
*/
|
||||
enum MDEventCategory implements JsonSerializable {
|
||||
|
||||
case production;
|
||||
case post_production;
|
||||
case pre_production;
|
||||
case no_production;
|
||||
|
||||
/**
|
||||
* Returns an MDEventCategory based on a given event type.
|
||||
*
|
||||
* @param integer $event_type Event type.
|
||||
*
|
||||
* @return MDEventCategory
|
||||
*/
|
||||
public static function fromEventType(int $event_type):MDEventCategory {
|
||||
|
||||
if (in_array($event_type, MDEventsSet::EVENTS_PRODUCTION, true)) {
|
||||
return self::production;
|
||||
}
|
||||
if (in_array($event_type, MDEventsSet::EVENTS_POST_PRODUCTION, true)) {
|
||||
return self::post_production;
|
||||
}
|
||||
if (in_array($event_type, MDEventsSet::EVENTS_PRE_PRODUCTION, true)) {
|
||||
return self::pre_production;
|
||||
}
|
||||
if (in_array($event_type, MDEventsSet::EVENTS_NO_PRODUCTION, true)) {
|
||||
return self::no_production;
|
||||
}
|
||||
if ($event_type === 5) {
|
||||
return self::no_production;
|
||||
}
|
||||
throw new Exception("Uncategorized event type: " . $event_type);
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
* Lists all available names.
|
||||
*
|
||||
* @return array<string>
|
||||
*/
|
||||
public static function caseNames():array {
|
||||
|
||||
$output = [];
|
||||
|
||||
$cases = self::cases();
|
||||
foreach ($cases as $case) {
|
||||
$output[] = $case->name;
|
||||
}
|
||||
|
||||
return $output;
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
* Provides the option to serialize as a string during json_encode().
|
||||
*
|
||||
* @return string
|
||||
*/
|
||||
public function jsonSerialize():string {
|
||||
|
||||
return $this->name;
|
||||
|
||||
}
|
||||
}
|
616
src/Checks/Plausi/MDPlausi.php
Normal file
616
src/Checks/Plausi/MDPlausi.php
Normal file
@ -0,0 +1,616 @@
|
||||
<?PHP
|
||||
/**
|
||||
* Plausability checker for object events.
|
||||
*
|
||||
* @author Joshua Ramon Enslin <joshua@museum-digital.de>
|
||||
*/
|
||||
declare(strict_types = 1);
|
||||
|
||||
/**
|
||||
* Plausability checker for object events.
|
||||
*/
|
||||
final class MDPlausi {
|
||||
|
||||
const UNKNOWN_TIME_MAX = MDRequirementsSet::TIME_LATEST_YEAR;
|
||||
const UNKNOWN_TIME_MIN = MDRequirementsSet::TIME_EARLIEST_YEAR;
|
||||
|
||||
private readonly int $default_time_max;
|
||||
private readonly int $default_time_min;
|
||||
|
||||
private MDTlLoader $_tlLoader;
|
||||
|
||||
/** @var array<MDPlausiEvent> */
|
||||
private array $_events;
|
||||
/** @var array<string> */
|
||||
private array $_messageList = [];
|
||||
private bool $_hasCertainWarnings = false; // True === 'alarm'
|
||||
|
||||
private bool $_is_print_material;
|
||||
private bool $_is_painted_drawn;
|
||||
|
||||
private MDPlausiEventCategory $_production;
|
||||
private MDPlausiEventCategory $_pre_production;
|
||||
private MDPlausiEventCategory $_post_production;
|
||||
private MDPlausiEventCategory $_printing_plate;
|
||||
private MDPlausiEventCategory $_template_creation;
|
||||
|
||||
/**
|
||||
* Checks whether events themselves are logical regarding the birth and
|
||||
* death dates vis-a-vis the stated time.
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
private function _checkPlausibilityOnBirthDeath():void {
|
||||
|
||||
if (empty($this->_events)) return;
|
||||
|
||||
// Get values for time_entries and actor_life dates from nodac
|
||||
|
||||
foreach ($this->_events as $event) {
|
||||
|
||||
// Evaluating actor birth
|
||||
if ($event->actor_birth_normalized !== false) {
|
||||
|
||||
// Work on the object started before the actor was born
|
||||
if ($event->time_start_normalized !== false && $event->time_start_normalized < $event->actor_birth_normalized) {
|
||||
$this->_messageList[] = '<b>' . $this->_tlLoader->tl("eventtype_name", "eventname", (string)$event->event_type) . '</b> (' . $event->time_name . ') ' . $this->_tlLoader->tl("quality", "quality", "before_birth_possibly") . ' ' . $event->actor_name;
|
||||
}
|
||||
|
||||
// The actor was involved with the object totally before they were born
|
||||
// Ended being involved before birth
|
||||
|
||||
else if ($event->time_end_normalized !== false && $event->time_end_normalized < $event->actor_birth_normalized) {
|
||||
$this->_messageList[] = '<b>' . $this->_tlLoader->tl("eventtype_name", "eventname", (string)$event->event_type) . '</b> (' . $event->time_name . ') ' . $this->_tlLoader->tl("quality", "quality", "before_birth") . ' ' . $event->actor_name;
|
||||
$this->_hasCertainWarnings = true;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
// Evaluate actor death
|
||||
if ($event->actor_death_normalized !== false) {
|
||||
|
||||
// Check if the actor died before they started being involved with the object
|
||||
if ($event->time_start_normalized !== false && $event->actor_death_normalized < $event->time_start_normalized) {
|
||||
$this->_messageList[] = '<b>' . $this->_tlLoader->tl("eventtype_name", "eventname", (string)$event->event_type) . '</b> (' . $event->time_name . ') ' . $this->_tlLoader->tl("quality", "quality", "after_death") . ' ' . $event->actor_name;
|
||||
$this->_hasCertainWarnings = true;
|
||||
}
|
||||
else if ($event->time_end_normalized !== false && $event->actor_death_normalized < $event->time_end_normalized) {
|
||||
$this->_messageList[] = '<b>' . $this->_tlLoader->tl("eventtype_name", "eventname", (string)$event->event_type) . '</b> (' . $event->time_name . ') ' . $this->_tlLoader->tl("quality", "quality", "after_death_possibly") . ' ' . $event->actor_name;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
* Evaluates the relation between template creation, printing plate or drawing dates.
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
public function _evaluateTemplateStatus():void {
|
||||
|
||||
// Printing plate was produced before template was even started
|
||||
if ($this->_printing_plate->latest_event_type !== 0
|
||||
&& $this->_template_creation->earliest_event_type !== 0
|
||||
&& $this->_printing_plate->latest < $this->_template_creation->earliest) {
|
||||
|
||||
$message = '<b>' . $this->_tlLoader->tl("eventtype_name", "eventname", "12") . '</b>';
|
||||
|
||||
$message .= $this->_printing_plate->formulateMessagePartForLatest($this->_tlLoader);
|
||||
|
||||
$message .= ' ' . $this->_tlLoader->tl("quality", "quality", "before") . ' <b>' . $this->_tlLoader->tl("eventtype_name", "eventname", "4") . '</b>';
|
||||
|
||||
$message .= $this->_template_creation->formulateMessagePartForEarliest($this->_tlLoader);
|
||||
|
||||
$this->_messageList[] = $message;
|
||||
$this->_hasCertainWarnings = true;
|
||||
|
||||
}
|
||||
// Printing plate was produced before template was finished
|
||||
else if ($this->_printing_plate->latest_event_type !== 0
|
||||
&& $this->_template_creation->latest_event_type !== 0
|
||||
&& $this->_printing_plate->latest < $this->_template_creation->latest) {
|
||||
|
||||
$message = '<b>' . $this->_tlLoader->tl("eventtype_name", "eventname", "12") . '</b>';
|
||||
|
||||
$message .= $this->_printing_plate->formulateMessagePartForLatest($this->_tlLoader);
|
||||
|
||||
$message .= ' ' . $this->_tlLoader->tl("quality", "quality", "before_possibly") . ' <b>' . $this->_tlLoader->tl("eventtype_name", "eventname", "4") . '</b>';
|
||||
|
||||
$message .= $this->_template_creation->formulateMessagePartForLatest($this->_tlLoader);
|
||||
|
||||
$this->_messageList[] = $message;
|
||||
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
* Adds a warning message if an object was both drawn and printed
|
||||
* (prints of drawn materials make the drawing a template).
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
private function _evaluateDrawingsWhichArePrinted():void {
|
||||
|
||||
// Paintings should not be printed at the same time
|
||||
if ($this->_is_painted_drawn === true and $this->_is_print_material === true) {
|
||||
|
||||
$message = '<b>' . $this->_tlLoader->tl("quality", "quality", "print_not_paint") . '</b> ' . $this->_tlLoader->tl("quality", "quality", "better_use") . ' "' . $this->_tlLoader->tl("eventtype_name", "eventname", "4") . '" . ';
|
||||
$this->_hasCertainWarnings = true;
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
* Evaluates if an object's preproduction (e.g. template) took place after the object was
|
||||
* already produced.
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
private function _evaluatePreproductionAfterProduction():void {
|
||||
|
||||
// Printing plate was produced before template was finished
|
||||
if ($this->_production->latest_event_type !== 0
|
||||
&& $this->_pre_production->earliest_event_type !== 0
|
||||
&& $this->_production->latest < $this->_pre_production->earliest) {
|
||||
|
||||
$message = '<b>' . $this->_tlLoader->tl("eventtype_name", "eventname", (string)$this->_production->latest_event_type) . '</b>';
|
||||
|
||||
$message .= $this->_production->formulateMessagePartForLatest($this->_tlLoader);
|
||||
|
||||
$message .= ' ' . $this->_tlLoader->tl("quality", "quality", "before") . ' <b>' . $this->_tlLoader->tl("eventtype_name", "eventname", (string)$this->_pre_production->earliest_event_type) . '</b>';
|
||||
|
||||
$message .= $this->_pre_production->formulateMessagePartForEarliest($this->_tlLoader);
|
||||
|
||||
$this->_messageList[] = $message;
|
||||
$this->_hasCertainWarnings = true;
|
||||
|
||||
}
|
||||
|
||||
// Printing plate was produced before template was finished
|
||||
else if ($this->_production->latest_event_type !== 0
|
||||
&& $this->_pre_production->latest_event_type !== 0
|
||||
&& $this->_production->latest < $this->_pre_production->latest) {
|
||||
|
||||
$message = '<b>' . $this->_tlLoader->tl("eventtype_name", "eventname", (string)$this->_production->latest_event_type) . '</b>';
|
||||
|
||||
$message .= $this->_production->formulateMessagePartForLatest($this->_tlLoader);
|
||||
|
||||
$message .= ' ' . $this->_tlLoader->tl("quality", "quality", "before_possibly") . ' <b>' . $this->_tlLoader->tl("eventtype_name", "eventname", (string)$this->_pre_production->latest_event_type) . '</b>';
|
||||
|
||||
$message .= $this->_pre_production->formulateMessagePartForLatest($this->_tlLoader);
|
||||
|
||||
$this->_messageList[] = $message;
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
* Evaluates if an object's preproduction (e.g. template) took place after the object was
|
||||
* already being used (or otherwise interacted with past it's completion).
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
private function _evaluatePreproductionAfterPostproduction():void {
|
||||
|
||||
// Printing plate was postproduced before template was finished
|
||||
if ($this->_post_production->latest_event_type !== 0
|
||||
&& $this->_pre_production->earliest_event_type !== 0
|
||||
&& $this->_post_production->latest < $this->_pre_production->earliest) {
|
||||
|
||||
$message = '<b>' . $this->_tlLoader->tl("eventtype_name", "eventname", (string)$this->_post_production->latest_event_type) . '</b>';
|
||||
|
||||
$message .= $this->_post_production->formulateMessagePartForLatest($this->_tlLoader);
|
||||
|
||||
$message .= ' ' . $this->_tlLoader->tl("quality", "quality", "before") . ' <b>' . $this->_tlLoader->tl("eventtype_name", "eventname", (string)$this->_pre_production->earliest_event_type) . '</b>';
|
||||
|
||||
$message .= $this->_pre_production->formulateMessagePartForEarliest($this->_tlLoader);
|
||||
|
||||
$this->_messageList[] = $message;
|
||||
$this->_hasCertainWarnings = true;
|
||||
|
||||
}
|
||||
|
||||
// E.g. template creation after being all use was finished
|
||||
else if ($this->_post_production->latest_event_type !== 0
|
||||
&& $this->_pre_production->latest_event_type !== 0
|
||||
&& $this->_post_production->latest < $this->_pre_production->latest) {
|
||||
|
||||
$message = '<b>' . $this->_tlLoader->tl("eventtype_name", "eventname", (string)$this->_post_production->latest_event_type) . '</b>';
|
||||
|
||||
$message .= $this->_post_production->formulateMessagePartForLatest($this->_tlLoader);
|
||||
|
||||
$message .= ' ' . $this->_tlLoader->tl("quality", "quality", "before") . ' <b>' . $this->_tlLoader->tl("eventtype_name", "eventname", (string)$this->_pre_production->latest_event_type) . '</b>';
|
||||
|
||||
$message .= $this->_pre_production->formulateMessagePartForLatest($this->_tlLoader);
|
||||
|
||||
$this->_messageList[] = $message;
|
||||
$this->_hasCertainWarnings = true;
|
||||
|
||||
}
|
||||
|
||||
// E.g. template creation was only started after the object was beyond use
|
||||
// This may happen, if the template is for renovations or so. Hence, there is
|
||||
// only a warning here.
|
||||
else if ($this->_post_production->earliest_event_type !== 0
|
||||
&& $this->_pre_production->earliest_event_type !== 0
|
||||
&& $this->_post_production->earliest < $this->_pre_production->earliest) {
|
||||
|
||||
$message = '<b>' . $this->_tlLoader->tl("eventtype_name", "eventname", (string)$this->_post_production->earliest_event_type) . '</b>';
|
||||
|
||||
$message .= $this->_post_production->formulateMessagePartForEarliest($this->_tlLoader);
|
||||
|
||||
$message .= ' ' . $this->_tlLoader->tl("quality", "quality", "before_possibly") . ' <b>' . $this->_tlLoader->tl("eventtype_name", "eventname", (string)$this->_pre_production->earliest_event_type) . '</b>';
|
||||
|
||||
$message .= $this->_pre_production->formulateMessagePartForEarliest($this->_tlLoader);
|
||||
|
||||
$this->_messageList[] = $message;
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
* Evaluates if an object's production (e.g. template) took place after the object was
|
||||
* already being used (or otherwise interacted with past it's completion).
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
private function _evaluateProductionAfterPostproduction():void {
|
||||
|
||||
if ($this->_post_production->earliest_event_type !== 0
|
||||
&& $this->_production->earliest_event_type !== 0
|
||||
&& $this->_post_production->earliest < $this->_production->earliest) {
|
||||
|
||||
$message = '<b>' . $this->_tlLoader->tl("eventtype_name", "eventname", (string)$this->_post_production->earliest_event_type) . '</b>';
|
||||
|
||||
$message .= $this->_post_production->formulateMessagePartForEarliest($this->_tlLoader);
|
||||
|
||||
$message .= ' ' . $this->_tlLoader->tl("quality", "quality", "before") . ' <b>' . $this->_tlLoader->tl("eventtype_name", "eventname", (string)$this->_production->earliest_event_type) . '</b>';
|
||||
|
||||
$message .= $this->_production->formulateMessagePartForEarliest($this->_tlLoader);
|
||||
|
||||
$this->_messageList[] = $message;
|
||||
$this->_hasCertainWarnings = true;
|
||||
|
||||
}
|
||||
|
||||
else if ($this->_post_production->earliest_event_type !== 0
|
||||
&& $this->_production->latest_event_type !== 0
|
||||
&& $this->_post_production->earliest < $this->_production->latest) {
|
||||
|
||||
$message = '<b>' . $this->_tlLoader->tl("eventtype_name", "eventname", (string)$this->_post_production->earliest_event_type) . '</b>';
|
||||
|
||||
$message .= $this->_post_production->formulateMessagePartForEarliest($this->_tlLoader);
|
||||
|
||||
$message .= ' ' . $this->_tlLoader->tl("quality", "quality", "before_possibly") . ' <b>' . $this->_tlLoader->tl("eventtype_name", "eventname", (string)$this->_production->latest_event_type) . '</b>';
|
||||
|
||||
$message .= $this->_production->formulateMessagePartForLatest($this->_tlLoader);
|
||||
|
||||
$this->_messageList[] = $message;
|
||||
|
||||
}
|
||||
else if ($this->_post_production->latest_event_type !== 0
|
||||
&& $this->_production->latest_event_type !== 0
|
||||
&& $this->_post_production->latest < $this->_production->latest) {
|
||||
|
||||
$message = '<b>' . $this->_tlLoader->tl("eventtype_name", "eventname", (string)$this->_post_production->latest_event_type) . '</b>';
|
||||
|
||||
$message .= $this->_post_production->formulateMessagePartForLatest($this->_tlLoader);
|
||||
|
||||
$message .= ' ' . $this->_tlLoader->tl("quality", "quality", "before_possibly") . ' <b>' . $this->_tlLoader->tl("eventtype_name", "eventname", (string)$this->_production->latest_event_type) . '</b>';
|
||||
|
||||
$message .= $this->_production->formulateMessagePartForLatest($this->_tlLoader);
|
||||
|
||||
$this->_messageList[] = $message;
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
* Warns if an actor was displayed on an object finished before they were born.
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
private function _checkActorDisplayedBeforeBirth():void {
|
||||
|
||||
foreach ($this->_events as $event) {
|
||||
|
||||
// Ignore events other than "was displayed"
|
||||
if ($event->event_type !== 5) continue;
|
||||
|
||||
if ($event->actor_birth_normalized !== false
|
||||
&& $this->_production->latest_event_type !== 0
|
||||
&& $event->actor_birth_normalized > $this->_production->latest
|
||||
) {
|
||||
|
||||
$message = '<b>' . $this->_tlLoader->tl("eventtype_name", "eventname", (string)$this->_production->latest_event_type) . '</b>';
|
||||
|
||||
$message .= $this->_production->formulateMessagePartForLatest($this->_tlLoader);
|
||||
|
||||
$message .= ' ' . $this->_tlLoader->tl("quality", "quality", "before") . ' <b>' . $this->_tlLoader->tl("eventtype_name", "eventname", "5") . '</b>';
|
||||
$message .= ' (' . $this->_tlLoader->tl("basis", "basis", "actor_short") . ': ' . $event->actor_name . ' (* ' . $event->actor_birth . '))';
|
||||
|
||||
$this->_messageList[] = $message;
|
||||
$this->_hasCertainWarnings = true;
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
* Checks plausibility by event category.
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
private function _checkIllogicalEventsByCategory():void {
|
||||
|
||||
$this->_evaluateTemplateStatus();
|
||||
$this->_evaluateDrawingsWhichArePrinted();
|
||||
$this->_evaluatePreproductionAfterProduction();
|
||||
$this->_evaluatePreproductionAfterPostproduction();
|
||||
$this->_evaluateProductionAfterPostproduction();
|
||||
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Runs the available evaluations.
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
public function evaluate():void {
|
||||
|
||||
$this->_checkPlausibilityOnBirthDeath();
|
||||
$this->_checkIllogicalEventsByCategory();
|
||||
$this->_checkActorDisplayedBeforeBirth();
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
* Setup function for setting event categories.
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
public function _categorizeEvents():void {
|
||||
|
||||
foreach ($this->_events as $event) {
|
||||
|
||||
if ($event->actor_death_normalized !== false) {
|
||||
$actor_death = date("Y", $event->actor_death_normalized);
|
||||
}
|
||||
else $actor_death = self::UNKNOWN_TIME_MIN;
|
||||
|
||||
switch ($event->event_category) {
|
||||
case MDEventCategory::production:
|
||||
|
||||
if ($event->time_start_normalized !== false && $this->_production->earliest > $event->time_start_normalized) {
|
||||
$this->_production->earliest = $event->time_start_normalized;
|
||||
$this->_production->earliest_name = $event->time_name;
|
||||
$this->_production->earliest_time_name = $event->time_start;
|
||||
$this->_production->earliest_source = 'time';
|
||||
$this->_production->earliest_event_type = $event->event_type;
|
||||
}
|
||||
if ($event->time_end_normalized !== false && $this->_production->latest < $event->time_end_normalized) {
|
||||
$this->_production->latest = $event->time_end_normalized;
|
||||
$this->_production->latest_name = $event->time_name;
|
||||
$this->_production->latest_time_name = $event->time_end;
|
||||
$this->_production->latest_source = 'time';
|
||||
$this->_production->latest_event_type = $event->event_type;
|
||||
}
|
||||
if ($event->actor_birth_normalized !== false && $this->_production->earliest > $event->actor_birth_normalized) {
|
||||
$this->_production->earliest = $event->actor_birth_normalized;
|
||||
$this->_production->earliest_name = $event->actor_name;
|
||||
$this->_production->earliest_time_name = $event->actor_birth;
|
||||
$this->_production->earliest_source = 'actor';
|
||||
$this->_production->earliest_event_type = $event->event_type;
|
||||
}
|
||||
if ($event->actor_death_normalized !== false && $this->_production->latest < $event->actor_death_normalized) {
|
||||
$this->_production->latest = $event->actor_death_normalized;
|
||||
$this->_production->latest_name = $event->actor_name;
|
||||
$this->_production->latest_time_name = $event->actor_death;
|
||||
$this->_production->latest_source = 'actor';
|
||||
$this->_production->latest_event_type = $event->event_type;
|
||||
}
|
||||
|
||||
break;
|
||||
|
||||
case MDEventCategory::pre_production:
|
||||
|
||||
if ($event->time_start_normalized !== false && $this->_pre_production->earliest > $event->time_start_normalized) {
|
||||
$this->_pre_production->earliest = $event->time_start_normalized;
|
||||
$this->_pre_production->earliest_name = $event->time_name;
|
||||
$this->_pre_production->earliest_time_name = $event->time_start;
|
||||
$this->_pre_production->earliest_source = 'time';
|
||||
$this->_pre_production->earliest_event_type = $event->event_type;
|
||||
}
|
||||
if ($event->time_end_normalized !== false && $this->_pre_production->latest < $event->time_end_normalized) {
|
||||
$this->_pre_production->latest = $event->time_end_normalized;
|
||||
$this->_pre_production->latest_name = $event->time_name;
|
||||
$this->_pre_production->latest_time_name = $event->time_end;
|
||||
$this->_pre_production->latest_source = 'time';
|
||||
$this->_pre_production->latest_event_type = $event->event_type;
|
||||
}
|
||||
if ($event->actor_birth_normalized !== false && $this->_pre_production->earliest > $event->actor_birth_normalized) {
|
||||
$this->_pre_production->earliest = $event->actor_birth_normalized;
|
||||
$this->_pre_production->earliest_name = $event->actor_name;
|
||||
$this->_pre_production->earliest_time_name = $event->actor_birth;
|
||||
$this->_pre_production->earliest_source = 'actor';
|
||||
$this->_pre_production->earliest_event_type = $event->event_type;
|
||||
}
|
||||
if ($event->actor_death_normalized !== false && $this->_pre_production->latest < $event->actor_death_normalized) {
|
||||
$this->_pre_production->latest = $event->actor_death_normalized;
|
||||
$this->_pre_production->latest_name = $event->actor_name;
|
||||
$this->_pre_production->latest_time_name = $event->actor_death;
|
||||
$this->_pre_production->latest_source = 'actor';
|
||||
$this->_pre_production->latest_event_type = $event->event_type;
|
||||
}
|
||||
|
||||
break;
|
||||
case MDEventCategory::post_production:
|
||||
|
||||
if ($event->time_start_normalized !== false && $this->_post_production->earliest > $event->time_start_normalized) {
|
||||
$this->_post_production->earliest = $event->time_start_normalized;
|
||||
$this->_post_production->earliest_name = $event->time_name;
|
||||
$this->_post_production->earliest_time_name = $event->time_start;
|
||||
$this->_post_production->earliest_source = 'time';
|
||||
$this->_post_production->earliest_event_type = $event->event_type;
|
||||
}
|
||||
if ($event->time_end_normalized !== false && $this->_post_production->latest < $event->time_end_normalized) {
|
||||
$this->_post_production->latest = $event->time_end_normalized;
|
||||
$this->_post_production->latest_name = $event->time_name;
|
||||
$this->_post_production->latest_time_name = $event->time_end;
|
||||
$this->_post_production->latest_source = 'time';
|
||||
$this->_post_production->latest_event_type = $event->event_type;
|
||||
}
|
||||
if ($event->actor_birth_normalized !== false && $this->_post_production->earliest > $event->actor_birth_normalized) {
|
||||
$this->_post_production->earliest = $event->actor_birth_normalized;
|
||||
$this->_post_production->earliest_name = $event->actor_name;
|
||||
$this->_post_production->earliest_time_name = $event->actor_birth;
|
||||
$this->_post_production->earliest_source = 'actor';
|
||||
$this->_post_production->earliest_event_type = $event->event_type;
|
||||
}
|
||||
if ($event->actor_death_normalized !== false && $this->_post_production->latest < $event->actor_death_normalized) {
|
||||
$this->_post_production->latest = $event->actor_death_normalized;
|
||||
$this->_post_production->latest_name = $event->actor_name;
|
||||
$this->_post_production->latest_time_name = $event->actor_death;
|
||||
$this->_post_production->latest_source = 'actor';
|
||||
$this->_post_production->latest_event_type = $event->event_type;
|
||||
}
|
||||
|
||||
break;
|
||||
}
|
||||
|
||||
if ($event->event_type === 9 || $event->event_type === 19) {
|
||||
$this->_is_painted_drawn = true;
|
||||
}
|
||||
if ($event->event_type === 4) {
|
||||
|
||||
if ($event->time_start_normalized !== false && $this->_template_creation->earliest > $event->time_start_normalized) {
|
||||
$this->_template_creation->earliest = $event->time_start_normalized;
|
||||
$this->_template_creation->earliest_name = $event->time_name;
|
||||
$this->_template_creation->earliest_time_name = $event->time_start;
|
||||
$this->_template_creation->earliest_source = 'time';
|
||||
$this->_template_creation->earliest_event_type = $event->event_type;
|
||||
}
|
||||
if ($event->time_end_normalized !== false && $this->_template_creation->latest < $event->time_end_normalized) {
|
||||
$this->_template_creation->latest = $event->time_end_normalized;
|
||||
$this->_template_creation->latest_name = $event->time_name;
|
||||
$this->_template_creation->latest_time_name = $event->time_end;
|
||||
$this->_template_creation->latest_source = 'time';
|
||||
$this->_template_creation->latest_event_type = $event->event_type;
|
||||
}
|
||||
if ($event->actor_birth_normalized !== false && $this->_template_creation->earliest > $event->actor_birth_normalized) {
|
||||
$this->_template_creation->earliest = $event->actor_birth_normalized;
|
||||
$this->_template_creation->earliest_name = $event->actor_name;
|
||||
$this->_template_creation->earliest_time_name = $event->actor_birth;
|
||||
$this->_template_creation->earliest_source = 'actor';
|
||||
$this->_template_creation->earliest_event_type = $event->event_type;
|
||||
}
|
||||
if ($event->actor_death_normalized !== false && $this->_template_creation->latest < $event->actor_death_normalized) {
|
||||
$this->_template_creation->latest = $event->actor_death_normalized;
|
||||
$this->_template_creation->latest_name = $event->actor_name;
|
||||
$this->_template_creation->latest_time_name = $event->actor_death;
|
||||
$this->_template_creation->latest_source = 'actor';
|
||||
$this->_template_creation->latest_event_type = $event->event_type;
|
||||
}
|
||||
|
||||
}
|
||||
else if ($event->event_type === 12) {
|
||||
|
||||
if ($event->time_start_normalized !== false && $this->_printing_plate->earliest > $event->time_start_normalized) {
|
||||
$this->_printing_plate->earliest = $event->time_start_normalized;
|
||||
$this->_printing_plate->earliest_name = $event->time_name;
|
||||
$this->_printing_plate->earliest_time_name = $event->time_start;
|
||||
$this->_printing_plate->earliest_source = 'time';
|
||||
$this->_printing_plate->earliest_event_type = $event->event_type;
|
||||
}
|
||||
if ($event->time_end_normalized !== false && $this->_printing_plate->latest < $event->time_end_normalized) {
|
||||
$this->_printing_plate->latest = $event->time_end_normalized;
|
||||
$this->_printing_plate->latest_name = $event->time_name;
|
||||
$this->_printing_plate->latest_time_name = $event->time_end;
|
||||
$this->_printing_plate->latest_source = 'time';
|
||||
$this->_printing_plate->latest_event_type = $event->event_type;
|
||||
}
|
||||
if ($event->actor_birth_normalized !== false && $this->_printing_plate->earliest > $event->actor_birth_normalized) {
|
||||
$this->_printing_plate->earliest = $event->actor_birth_normalized;
|
||||
$this->_printing_plate->earliest_name = $event->actor_name;
|
||||
$this->_printing_plate->earliest_time_name = $event->actor_birth;
|
||||
$this->_printing_plate->earliest_source = 'actor';
|
||||
$this->_printing_plate->earliest_event_type = $event->event_type;
|
||||
}
|
||||
if ($event->actor_death_normalized !== false && $this->_printing_plate->latest < $event->actor_death_normalized) {
|
||||
$this->_printing_plate->latest = $event->actor_death_normalized;
|
||||
$this->_printing_plate->latest_name = $event->actor_name;
|
||||
$this->_printing_plate->latest_time_name = $event->actor_death;
|
||||
$this->_printing_plate->latest_source = 'actor';
|
||||
$this->_printing_plate->latest_event_type = $event->event_type;
|
||||
}
|
||||
$this->_is_print_material = true;
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
if (!isset($this->_is_painted_drawn)) $this->_is_painted_drawn = true;
|
||||
if (!isset($this->_is_print_material)) $this->_is_print_material = true;
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the message list.
|
||||
*
|
||||
* @return array<string>
|
||||
*/
|
||||
public function getMessages():array {
|
||||
|
||||
return $this->_messageList;
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the warning status.
|
||||
*
|
||||
* @return boolean
|
||||
*/
|
||||
public function getWarningStatus():bool {
|
||||
|
||||
return $this->_hasCertainWarnings;
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
* Constructor.
|
||||
*
|
||||
* @param MDTlLoader $tlLoader Translation loader.
|
||||
* @param array<MDPlausiEvent> $events Events.
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
public function __construct(MDTlLoader $tlLoader, array $events) {
|
||||
|
||||
$this->_tlLoader = $tlLoader;
|
||||
$this->_events = $events;
|
||||
|
||||
$this->default_time_max = time();
|
||||
$this->default_time_min = -99999999999999999;
|
||||
|
||||
$this->_production = new MDPlausiEventCategory($this->default_time_max, $this->default_time_min);
|
||||
$this->_pre_production = new MDPlausiEventCategory($this->default_time_max, $this->default_time_min);
|
||||
$this->_post_production = new MDPlausiEventCategory($this->default_time_max, $this->default_time_min);
|
||||
$this->_printing_plate = new MDPlausiEventCategory($this->default_time_max, $this->default_time_min);
|
||||
$this->_template_creation = new MDPlausiEventCategory($this->default_time_max, $this->default_time_min);
|
||||
|
||||
$this->_categorizeEvents();
|
||||
|
||||
}
|
||||
}
|
99
src/Checks/Plausi/MDPlausiEvent.php
Normal file
99
src/Checks/Plausi/MDPlausiEvent.php
Normal file
@ -0,0 +1,99 @@
|
||||
<?PHP
|
||||
/**
|
||||
* An event as required for the plausibility checker for events.
|
||||
*
|
||||
* @author Joshua Ramon Enslin <joshua@museum-digital.de>
|
||||
*/
|
||||
declare(strict_types = 1);
|
||||
|
||||
/**
|
||||
* An event as required for the plausibility checker for events.
|
||||
*/
|
||||
final class MDPlausiEvent {
|
||||
|
||||
public readonly int $event_type;
|
||||
public readonly MDEventCategory $event_category;
|
||||
|
||||
public readonly string $time_name;
|
||||
public readonly string $time_start;
|
||||
public readonly string $time_end;
|
||||
public readonly int|false $time_start_normalized;
|
||||
public readonly int|false $time_end_normalized;
|
||||
|
||||
public readonly string $actor_name;
|
||||
public readonly string $actor_birth;
|
||||
public readonly string $actor_death;
|
||||
public readonly int|false $actor_birth_normalized;
|
||||
public readonly int|false $actor_death_normalized;
|
||||
|
||||
/**
|
||||
* Attempts to parse a time.
|
||||
*
|
||||
* @param string $time Time to parse.
|
||||
*
|
||||
* @return array{earliest: int|false, latest: int|false}
|
||||
*/
|
||||
private function _attemptParsingTime(string $time):array {
|
||||
|
||||
if (empty($time)) return ['earliest' => false, 'latest' => false];
|
||||
|
||||
// 2005
|
||||
if (in_array(strlen($time), [4, 5], true) and is_numeric(substr($time, 1))) {
|
||||
return [
|
||||
'earliest' => strtotime($time . '-01-01'),
|
||||
'latest' => strtotime($time . '-12-31'),
|
||||
];
|
||||
}
|
||||
|
||||
// 2005-2006
|
||||
if (strlen($time) === 9) {
|
||||
$parts = explode('-', $time);
|
||||
if (count($parts) === 2) {
|
||||
return [
|
||||
'earliest' => strtotime($parts[0]. '-01-01'),
|
||||
'latest' => strtotime($parts[1]. '-12-31'),
|
||||
];
|
||||
}
|
||||
}
|
||||
|
||||
$strtotime = strtotime($time);
|
||||
return [
|
||||
'earliest' => $strtotime,
|
||||
'latest' => $strtotime,
|
||||
];
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
* Constructor.
|
||||
*
|
||||
* @param integer $event_type Event type.
|
||||
* @param string $time_name Time.
|
||||
* @param string $time_start Start.
|
||||
* @param string $time_end End.
|
||||
* @param string $actor_name Name of the linked actor.
|
||||
* @param string $actor_birth Birth of the linked actor.
|
||||
* @param string $actor_death Time of death of the linked actor.
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
public function __construct(int $event_type, string $time_name, string $time_start, string $time_end, string $actor_name, string $actor_birth, string $actor_death) {
|
||||
|
||||
$this->event_type = $event_type;
|
||||
$this->time_name = $time_name;
|
||||
$this->time_start = $time_start;
|
||||
$this->time_end = $time_end;
|
||||
$this->actor_name = $actor_name;
|
||||
$this->actor_birth = $actor_birth;
|
||||
$this->actor_death = $actor_death;
|
||||
|
||||
$this->time_start_normalized = $this->_attemptParsingTime($time_start)['earliest'];
|
||||
$this->time_end_normalized = $this->_attemptParsingTime($time_end)['latest'];
|
||||
|
||||
$this->actor_birth_normalized = $this->_attemptParsingTime($actor_birth)['earliest'];
|
||||
$this->actor_death_normalized = $this->_attemptParsingTime($actor_death)['latest'];
|
||||
|
||||
$this->event_category = MDEventCategory::fromEventType($event_type);
|
||||
|
||||
}
|
||||
}
|
78
src/Checks/Plausi/MDPlausiEventCategory.php
Normal file
78
src/Checks/Plausi/MDPlausiEventCategory.php
Normal file
@ -0,0 +1,78 @@
|
||||
<?PHP
|
||||
/**
|
||||
* Handles event category as used by MDPlausi.
|
||||
*
|
||||
* @author Joshua Ramon Enslin <joshua@museum-digital.de>
|
||||
*/
|
||||
declare(strict_types = 1);
|
||||
|
||||
/**
|
||||
* Handles event category as used by MDPlausi.
|
||||
*/
|
||||
final class MDPlausiEventCategory {
|
||||
|
||||
public int $earliest;
|
||||
public int $latest;
|
||||
public string $earliest_name = '';
|
||||
public string $latest_name = '';
|
||||
public string $earliest_time_name = '';
|
||||
public string $latest_time_name = '';
|
||||
|
||||
/** @var 'actor'|'time' */
|
||||
public string $earliest_source;
|
||||
/** @var 'actor'|'time' */
|
||||
public string $latest_source;
|
||||
public int $earliest_event_type = 0;
|
||||
public int $latest_event_type = 0;
|
||||
|
||||
/**
|
||||
* Formulates a plausi message part base on the earliest use of the category.
|
||||
*
|
||||
* @param MDTlLoader $tlLoader Translation loader.
|
||||
*
|
||||
* @return string
|
||||
*/
|
||||
public function formulateMessagePartForEarliest(MDTlLoader $tlLoader):string {
|
||||
|
||||
if ($this->earliest_source === 'actor') {
|
||||
return ' (' . $tlLoader->tl("basis", "basis", "actor_short") . ': ' . $this->earliest_name . ' (* ' . $this->earliest_time_name . '))';
|
||||
}
|
||||
else {
|
||||
return ' (' . $this->earliest_name . ')';
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
* Formulates a plausi message part base on the latest use of the category.
|
||||
*
|
||||
* @param MDTlLoader $tlLoader Translation loader.
|
||||
*
|
||||
* @return string
|
||||
*/
|
||||
public function formulateMessagePartForLatest(MDTlLoader $tlLoader):string {
|
||||
|
||||
if ($this->latest_source === 'actor') {
|
||||
return ' (' . $tlLoader->tl("basis", "basis", "actor_short") . ': ' . $this->latest_name . ' (✝ ' . $this->latest_time_name . '))';
|
||||
}
|
||||
else {
|
||||
return ' (' . $this->latest_name . ')';
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
* Constructor.
|
||||
*
|
||||
* @param int $default_earliest Default earliest time.
|
||||
* @param int $default_latest Default latest time.
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
public function __construct(int $default_earliest, int $default_latest) {
|
||||
|
||||
$this->earliest = $default_earliest;
|
||||
$this->latest = $default_latest;
|
||||
|
||||
}
|
||||
}
|
45
src/Checks/Plausi/MDPlausiStatus.php
Normal file
45
src/Checks/Plausi/MDPlausiStatus.php
Normal file
@ -0,0 +1,45 @@
|
||||
<?PHP
|
||||
/**
|
||||
* Represents the plausibility check status.
|
||||
*
|
||||
* @author Joshua Ramon Enslin <joshua@museum-digital.de>
|
||||
*/
|
||||
declare(strict_types = 1);
|
||||
|
||||
/**
|
||||
* Represents the plausibility check status.
|
||||
*/
|
||||
enum MDPlausiStatus implements JsonSerializable {
|
||||
|
||||
case alarm;
|
||||
case okay;
|
||||
|
||||
/**
|
||||
* Lists all available names.
|
||||
*
|
||||
* @return array<string>
|
||||
*/
|
||||
public static function caseNames():array {
|
||||
|
||||
$output = [];
|
||||
|
||||
$cases = self::cases();
|
||||
foreach ($cases as $case) {
|
||||
$output[] = $case->name;
|
||||
}
|
||||
|
||||
return $output;
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
* Provides the option to serialize as a string during json_encode().
|
||||
*
|
||||
* @return string
|
||||
*/
|
||||
public function jsonSerialize():string {
|
||||
|
||||
return $this->name;
|
||||
|
||||
}
|
||||
}
|
Loading…
x
Reference in New Issue
Block a user