2019-07-25 09:28:30 +02:00
|
|
|
<?php
|
|
|
|
abstract class DecayingModelBase
|
|
|
|
{
|
|
|
|
public function checkLoading()
|
|
|
|
{
|
|
|
|
return 'BONFIRE LIT';
|
|
|
|
}
|
|
|
|
|
2019-12-04 12:12:10 +01:00
|
|
|
|
|
|
|
protected function __extractTagBasename($tagName) {
|
|
|
|
$pieces = array();
|
|
|
|
if (preg_match('/^[^:="]+:[^:="]+="[^:="]+"$/i', $tagName)) {
|
|
|
|
$temp = explode(':', $tagName);
|
|
|
|
$pieces = array_merge(array($temp[0]), explode('=', $temp[1]));
|
|
|
|
$pieces['complete'] = $tagName;
|
|
|
|
$pieces['namespace'] = $pieces[0];
|
|
|
|
$pieces['predicate'] = $pieces[1];
|
|
|
|
$pieces['2tag'] = sprintf('%s:%s', $pieces[0], $pieces[1]);
|
|
|
|
$pieces['base'] = sprintf('%s:%s', $pieces[0], $pieces[1]);
|
|
|
|
} elseif (preg_match('/^[^:="]+:[^:="]+$/i', $tagName)) {
|
|
|
|
$pieces = explode(':', $tagName);
|
|
|
|
$pieces['complete'] = $tagName;
|
|
|
|
$pieces['namespace'] = $pieces[0];
|
|
|
|
$pieces['predicate'] = $pieces[1];
|
|
|
|
$pieces['2tag'] = sprintf('%s:%s', $pieces[0], $pieces[1]);
|
|
|
|
$pieces['base'] = $pieces[0];
|
|
|
|
}
|
|
|
|
return $pieces;
|
|
|
|
}
|
|
|
|
|
2019-08-22 15:56:32 +02:00
|
|
|
// Get effective taxonomy ratio based on taxonomies attached to the attribute
|
2019-12-04 12:12:10 +01:00
|
|
|
// Basically, it adapts the ratio defined in the model to fit the actual attached tags
|
2019-07-25 09:28:30 +02:00
|
|
|
protected function __getRatioScore($model, $tags)
|
|
|
|
{
|
|
|
|
$ratioScore = array();
|
|
|
|
$taxonomy_base_ratio = $model['DecayingModel']['parameters']['base_score_config'];
|
|
|
|
if (empty($taxonomy_base_ratio)) {
|
|
|
|
return array();
|
|
|
|
}
|
|
|
|
$total_score = 0.0;
|
|
|
|
foreach ($tags as $tag) {
|
2019-12-04 12:12:10 +01:00
|
|
|
$tagBaseName = $this->__extractTagBasename($tag['Tag']['name'])['base'];
|
|
|
|
if (isset($taxonomy_base_ratio[$tagBaseName]) && is_numeric($tag['Tag']['numerical_value'])) {
|
|
|
|
$total_score += floatval($taxonomy_base_ratio[$tagBaseName]);
|
2019-07-25 09:28:30 +02:00
|
|
|
}
|
|
|
|
}
|
|
|
|
foreach ($tags as $i => $tag) {
|
2019-12-04 12:12:10 +01:00
|
|
|
$tagBaseName = $this->__extractTagBasename($tag['Tag']['name'])['base'];
|
|
|
|
if (isset($taxonomy_base_ratio[$tagBaseName]) && is_numeric($tag['Tag']['numerical_value'])) {
|
|
|
|
$ratioScore[$tagBaseName] = floatval($taxonomy_base_ratio[$tagBaseName]) / $total_score;
|
2019-07-25 09:28:30 +02:00
|
|
|
}
|
|
|
|
}
|
|
|
|
return $ratioScore;
|
|
|
|
}
|
|
|
|
|
2019-12-04 12:12:10 +01:00
|
|
|
// return attribute tag with event tag matching the tag basename overridden
|
2019-09-12 11:28:32 +02:00
|
|
|
protected function __getPrioritisedTag($attribute)
|
2019-07-25 09:28:30 +02:00
|
|
|
{
|
|
|
|
$tags = array();
|
|
|
|
$overridden_tags = array();
|
|
|
|
$temp_mapping = array();
|
2019-08-12 16:34:26 +02:00
|
|
|
if (isset($attribute['EventTag'])) {
|
|
|
|
foreach ($attribute['EventTag'] as $i => $tag) {
|
2019-07-25 15:45:33 +02:00
|
|
|
$tags[] = $tag;
|
2019-12-04 12:12:10 +01:00
|
|
|
$tagBaseName = $this->__extractTagBasename($tag['Tag']['name'])['base'];
|
|
|
|
$temp_mapping[$tagBaseName][] = $i;
|
2019-07-25 15:45:33 +02:00
|
|
|
}
|
2019-07-25 09:28:30 +02:00
|
|
|
}
|
2019-08-13 15:54:03 +02:00
|
|
|
if (isset($attribute['AttributeTag'])) {
|
|
|
|
foreach ($attribute['AttributeTag'] as $tag) {
|
2019-12-04 12:12:10 +01:00
|
|
|
$tagBaseName = $this->__extractTagBasename($tag['Tag']['name'])['base'];
|
|
|
|
if (!empty($temp_mapping[$tagBaseName])) { // need to override event tag
|
|
|
|
foreach ($temp_mapping[$tagBaseName] as $i => $eventtag_index) {
|
2019-09-12 13:26:26 +02:00
|
|
|
$overridden_tags[] = array(
|
|
|
|
'EventTag' => $tags[$eventtag_index],
|
|
|
|
'AttributeTag' => $tag
|
|
|
|
);
|
|
|
|
if ($i === 0) { // override first one
|
|
|
|
$tags[$eventtag_index] = $tag;
|
|
|
|
} else { // remove remaining overriden
|
|
|
|
unset($tags[$eventtag_index]);
|
|
|
|
}
|
|
|
|
}
|
2019-08-13 15:54:03 +02:00
|
|
|
} else {
|
|
|
|
$tags[] = $tag;
|
|
|
|
}
|
2019-07-25 09:28:30 +02:00
|
|
|
}
|
|
|
|
}
|
2019-09-12 13:26:26 +02:00
|
|
|
return array('tags' => array_values($tags), 'overridden' => $overridden_tags);
|
2019-07-25 09:28:30 +02:00
|
|
|
}
|
|
|
|
|
|
|
|
public function computeBasescore($model, $attribute)
|
|
|
|
{
|
2019-09-12 11:46:12 +02:00
|
|
|
$temp = $this->__getPrioritisedTag($attribute);
|
2019-07-25 09:28:30 +02:00
|
|
|
$tags = $temp['tags'];
|
|
|
|
$overridden_tags = $temp['overridden'];
|
|
|
|
$taxonomy_effective_ratios = $this->__getRatioScore($model, $tags);
|
|
|
|
$default_base_score = isset($model['DecayingModel']['parameters']['default_base_score']) ? $model['DecayingModel']['parameters']['default_base_score'] : 0 ;
|
2019-08-20 09:25:48 +02:00
|
|
|
$base_score = 0;
|
|
|
|
$flag_contain_matching_taxonomy = false;
|
2019-07-25 09:28:30 +02:00
|
|
|
if (!empty($taxonomy_effective_ratios)) {
|
|
|
|
foreach ($tags as $k => $tag) {
|
2019-08-28 10:09:35 +02:00
|
|
|
$taxonomy = explode('=', $tag['Tag']['name'])[0];
|
2019-07-25 09:28:30 +02:00
|
|
|
if (isset($taxonomy_effective_ratios[$taxonomy])) {
|
2019-08-20 09:25:48 +02:00
|
|
|
$flag_contain_matching_taxonomy = true;
|
2019-07-25 09:28:30 +02:00
|
|
|
$base_score += $taxonomy_effective_ratios[$taxonomy] * $tag['Tag']['numerical_value'];
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
2019-08-20 09:25:48 +02:00
|
|
|
if (!$flag_contain_matching_taxonomy) {
|
|
|
|
$base_score = $default_base_score;
|
|
|
|
}
|
2019-09-12 11:28:32 +02:00
|
|
|
return array(
|
|
|
|
'base_score' => $base_score,
|
|
|
|
'overridden' => $overridden_tags,
|
|
|
|
'tags' => $tags,
|
|
|
|
'taxonomy_effective_ratios' => $taxonomy_effective_ratios,
|
|
|
|
'default_base_score' => $default_base_score
|
|
|
|
);
|
2019-07-25 09:28:30 +02:00
|
|
|
}
|
|
|
|
|
2019-08-22 15:56:32 +02:00
|
|
|
// Compute the current score for the provided attribute according to the last sighting with the provided model
|
2019-07-25 15:45:33 +02:00
|
|
|
final public function computeCurrentScore($user, $model, $attribute, $base_score = false, $last_sighting_timestamp = false)
|
2019-07-25 09:28:30 +02:00
|
|
|
{
|
|
|
|
if ($base_score === false) {
|
|
|
|
$base_score = $this->computeBasescore($model, $attribute)['base_score'];
|
|
|
|
}
|
|
|
|
if ($last_sighting_timestamp === false) {
|
|
|
|
$this->Sighting = ClassRegistry::init('Sighting');
|
2019-08-12 16:34:26 +02:00
|
|
|
$all_sightings = $this->Sighting->listSightings($user, $attribute['id'], 'attribute', false, 0, true);
|
2019-07-25 15:45:33 +02:00
|
|
|
if (!empty($all_sightings)) {
|
|
|
|
$last_sighting_timestamp = $all_sightings[0]['Sighting']['date_sighting'];
|
|
|
|
} else {
|
2019-08-12 16:34:26 +02:00
|
|
|
$last_sighting_timestamp = $attribute['timestamp']; // if no sighting, take the last update time
|
2019-07-25 15:45:33 +02:00
|
|
|
}
|
2019-07-25 09:28:30 +02:00
|
|
|
}
|
2019-08-20 12:02:17 +02:00
|
|
|
if ($attribute['timestamp'] > $last_sighting_timestamp) { // The attribute was modified after the last sighting
|
|
|
|
$last_sighting_timestamp = $attribute['timestamp'];
|
|
|
|
}
|
2019-07-25 09:28:30 +02:00
|
|
|
$timestamp = time();
|
|
|
|
return $this->computeScore($model, $attribute, $base_score, $timestamp - $last_sighting_timestamp);
|
|
|
|
}
|
|
|
|
|
2019-08-22 15:56:32 +02:00
|
|
|
// Compute the score for the provided attribute according to the elapsed time with the provided model
|
2019-07-25 09:28:30 +02:00
|
|
|
abstract public function computeScore($model, $attribute, $base_score, $elapsed_time);
|
2019-08-22 15:56:32 +02:00
|
|
|
// Return a True if the attribute should be marked as decayed
|
2019-07-25 16:13:42 +02:00
|
|
|
abstract public function isDecayed($model, $attribute, $score);
|
2019-07-25 09:28:30 +02:00
|
|
|
}
|