summaryrefslogtreecommitdiffstats
path: root/library/Icingadb/Hook/ExtensionHook/BaseExtensionHook.php
blob: dfefdcdec2f3bb119b8ecb27d331e799aa45f611 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
<?php

/* Icinga DB Web | (c) 2021 Icinga GmbH | GPLv2 */

namespace Icinga\Module\Icingadb\Hook\ExtensionHook;

use Icinga\Module\Icingadb\Hook\Common\HookUtils;

abstract class BaseExtensionHook
{
    use HookUtils;

    /** @var int Used as default return value for {@see BaseExtensionHook::getLocation()} */
    const IDENTIFY_LOCATION_BY_SECTION = -1;

    /** @var string Output section, right at the top */
    const OUTPUT_SECTION = 'output';

    /** @var string Graph section, below output */
    const GRAPH_SECTION = 'graph';

    /** @var string Detail section, below graphs */
    const DETAIL_SECTION = 'detail';

    /** @var string Action section, below action and note urls */
    const ACTION_SECTION = 'action';

    /** @var string Problem section, below comments and downtimes */
    const PROBLEM_SECTION = 'problem';

    /** @var string Related section, below groups and notification recipients */
    const RELATED_SECTION = 'related';

    /** @var string State section, below check statistics and performance data */
    const STATE_SECTION = 'state';

    /** @var string Config section, below custom variables and feature toggles */
    const CONFIG_SECTION = 'config';

    /**
     * Base locations for all known sections
     *
     * @var array<string, int>
     */
    const BASE_LOCATIONS = [
        self::OUTPUT_SECTION    => 1000,
        self::GRAPH_SECTION     => 1100,
        self::DETAIL_SECTION    => 1200,
        self::ACTION_SECTION    => 1300,
        self::PROBLEM_SECTION   => 1400,
        self::RELATED_SECTION   => 1500,
        self::STATE_SECTION     => 1600,
        self::CONFIG_SECTION    => 1700
    ];

    /** @var int This hook's location */
    private $location = self::IDENTIFY_LOCATION_BY_SECTION;

    /** @var string This hook's section */
    private $section = self::DETAIL_SECTION;

    /**
     * Set this hook's location
     *
     * Note that setting the location explicitly may override other widgets using the same location. But beware that
     * this applies to this hook's widget as well.
     *
     * Also, while the sections are guaranteed to always refer to the same general location, this guarantee is lost
     * when setting a location explicitly. The core and base locations may change at any time and any explicitly set
     * location will **not** adjust accordingly.
     *
     * @param int $location
     *
     * @return void
     */
    final public function setLocation(int $location)
    {
        $this->location = $location;
    }

    /**
     * Get this hook's location
     *
     * @return int
     */
    final public function getLocation(): int
    {
        return $this->location;
    }

    /**
     * Set this hook's section
     *
     * Sections are used to place widgets loosely in a general location. Using e.g. the `state` section this hook's
     * widget will always appear after the check statistics and performance data widgets.
     *
     * @param string $section
     *
     * @return void
     */
    final public function setSection(string $section)
    {
        $this->section = $section;
    }

    /**
     * Get this hook's section
     *
     * @return string
     */
    final public function getSection(): string
    {
        return $this->section;
    }

    /**
     * Union both arrays and sort the result by key
     *
     * @param array $coreElements
     * @param array $extensions
     *
     * @return array
     */
    final public static function injectExtensions(array $coreElements, array $extensions): array
    {
        $extensions += $coreElements;

        uksort($extensions, function ($a, $b) {
            if ($a < 1000 && $b >= 1000) {
                $b -= 1000;
                if (abs($a - $b) < 10 && abs($a % 100 - $b % 100) < 10) {
                    return -1;
                }
            } elseif ($b < 1000 && $a >= 1000) {
                $a -= 1000;
                if (abs($a - $b) < 10 && abs($a % 100 - $b % 100) < 10) {
                    return 1;
                }
            }

            return $a < $b ? -1 : ($a > $b ? 1 : 0);
        });

        return $extensions;
    }
}