knowledge-8.x-1.x-dev/src/Service/SequenceService.php
src/Service/SequenceService.php
<?php
namespace Drupal\knowledge\Service;
use Drupal\views\ResultRow;
/**
* Fills missing sequence in the view results.
*/
class SequenceService {
/**
* Fills the view results missing sequence.
*/
public static function fill($result) {
if (empty($result)) {
return $result;
}
$row = $result[0];
foreach (get_object_vars($row) as $key => $value) {
switch ($key) {
case 'visitors_hour':
case 'visitors_visitor_localtime':
$result = self::hours($result, $key);
break;
case 'visitors_day_of_month':
$result = self::dayOfMonth($result, $key);
break;
case 'visitors_day_of_week':
$result = self::daysOfWeek($result, $key);
break;
case 'visitors_day':
$result = self::days($result, $key);
break;
case 'knowledge_weekly':
$result = self::weeks($result, $key);
break;
case 'visitors_month':
$result = self::months($result, $key);
break;
default:
break;
}
}
return $result;
}
/**
* Fills the missing hours in the result.
*/
protected static function hours($result, $field) {
return self::integer($result, $field, 24);
}
/**
* Fills the missing date in the result.
*/
protected static function date($result, $field, $max) {
$rows = [];
$exclude_fields = [
'index',
'_entity',
'_relationship_entities',
$field,
];
$index = 0;
$this_week = strtotime('this week');
$two_years = strtotime('-2 years', $this_week);
$type = 'custom';
// Custom PHP date format if $type="custom".
$format = 'YW';
$timezone = NULL;
$langcode = NULL;
$date_formatter = \Drupal::service('date.formatter');
$expected = $date_formatter->format($two_years, $type, $format, $timezone, $langcode);
$last = $date_formatter->format($this_week, $type, $format, $timezone, $langcode);
$keys = array_keys(get_object_vars($result[0]));
$year = (int) substr($expected, 0, 4);
$month = (int) substr($expected, 4, 2);
foreach ($result as $row) {
while ($expected < $row->{$field}) {
$clone = new ResultRow();
$clone->{$field} = $expected;
$clone->index = $index;
foreach ($keys as $key) {
if (in_array($key, $exclude_fields)) {
continue;
}
$clone->{$key} = '0';
}
$rows[] = $clone;
$index += 1;
$month += 1;
if ($month > $max) {
$month = 1;
$year += 1;
}
$expected = $year . str_pad($month, 2, '0', STR_PAD_LEFT);
}
$row->index = $index;
$index += 1;
if (($expected == $row->{$field})) {
$month += 1;
if ($month > $max) {
$month = 1;
$year += 1;
}
}
$expected = $year . str_pad($month, 2, '0', STR_PAD_LEFT);
$rows[] = $row;
}
while ($expected != $last) {
$clone = new ResultRow();
$clone->{$field} = $expected;
$clone->index = $index;
foreach ($keys as $key) {
if (in_array($key, $exclude_fields)) {
continue;
}
$clone->{$key} = '0';
}
$rows[] = $clone;
$index += 1;
$month += 1;
if ($month > $max) {
$month = 1;
$year += 1;
}
$expected = $year . str_pad($month, 2, '0', STR_PAD_LEFT);
}
return $rows;
}
/**
* Fills the missing days in the result.
*/
protected static function days($result, $field) {
$format = 'Y-m-d';
$increment = '+1 day';
$rows = [];
$exclude_fields = [
'index',
'_entity',
'_relationship_entities',
$field,
];
$index = 0;
$expected = $result[0]->{$field};
foreach ($result as $row) {
while ($expected != $row->{$field}) {
$clone = new ResultRow();
$clone->{$field} = $expected;
$clone->index = $index;
foreach (get_object_vars($clone) as $key => $value) {
if (in_array($key, $exclude_fields)) {
continue;
}
$clone->{$key} = '0';
}
$rows[] = $clone;
$expected = date($format, strtotime($increment, strtotime($expected)));
$index += 1;
}
$expected = date($format, strtotime($increment, strtotime($expected)));
$rows[] = $row;
}
return $rows;
}
/**
* Fills the missing weeks in the result.
*/
protected static function weeks($result, $field) {
return self::date($result, $field, 53);
}
/**
* Fills the missing months in the result.
*/
protected static function months($result, $field) {
return self::date($result, $field, 12);
}
/**
* Fills the missing days of week in the result.
*/
protected static function daysOfWeek($result, $field) {
return self::integer($result, $field, 7);
}
/**
* Fills the missing days of month in the result.
*/
protected static function dayOfMonth($result, $field) {
return self::integer($result, $field, 32, 1);
}
/**
* Fills the missing integer in the result.
*/
protected static function integer($result, $field, $end, $start = 0) {
$exclude_fields = [
'index',
'_entity',
'_relationship_entities',
$field,
];
$rows = [];
$expected = $start;
$index = 0;
$row = NULL;
foreach ($result as $row) {
while ($expected != (int) $row->{$field}) {
$clone = clone $row;
$clone->{$field} = str_pad($expected, 2, '0', STR_PAD_LEFT);
$clone->index = $index;
foreach (get_object_vars($clone) as $key => $value) {
if (in_array($key, $exclude_fields)) {
continue;
}
$clone->{$key} = '0';
}
$rows[] = $clone;
$index += 1;
$expected += 1;
}
$row->index = $index;
$row->{$field} = str_pad($row->{$field}, 2, '0', STR_PAD_LEFT);
$rows[] = $row;
$index += 1;
$expected += 1;
}
while (!is_null($row) && $expected < $end) {
$clone = clone $row;
$clone->{$field} = str_pad($expected, 2, '0', STR_PAD_LEFT);
$clone->index = $index;
foreach (get_object_vars($clone) as $key => $value) {
if (in_array($key, $exclude_fields)) {
continue;
}
$clone->{$key} = '0';
}
$rows[] = $clone;
$index += 1;
$expected += 1;
}
return $rows;
}
}
