commit
b28f1c4038
|
@ -672,6 +672,12 @@
|
|||
"code": 59492,
|
||||
"src": "entypo"
|
||||
},
|
||||
{
|
||||
"uid": "p57wgnf4glngbchbucdi029iptu8oxb8",
|
||||
"css": "pin",
|
||||
"code": 59513,
|
||||
"src": "typicons"
|
||||
},
|
||||
{
|
||||
"uid": "c16a63e911bc47b46dc2a7129d2f0c46",
|
||||
"css": "down-small",
|
||||
|
|
|
@ -119,4 +119,5 @@
|
|||
.icon-down-small:before { content: '\e875'; } /* '' */
|
||||
.icon-left-small:before { content: '\e876'; } /* '' */
|
||||
.icon-right-small:before { content: '\e877'; } /* '' */
|
||||
.icon-up-small:before { content: '\e878'; } /* '' */
|
||||
.icon-up-small:before { content: '\e878'; } /* '' */
|
||||
.icon-pin:before { content: '\e879'; } /* '' */
|
File diff suppressed because one or more lines are too long
|
@ -119,4 +119,5 @@
|
|||
.icon-down-small { *zoom: expression( this.runtimeStyle['zoom'] = '1', this.innerHTML = ' '); }
|
||||
.icon-left-small { *zoom: expression( this.runtimeStyle['zoom'] = '1', this.innerHTML = ' '); }
|
||||
.icon-right-small { *zoom: expression( this.runtimeStyle['zoom'] = '1', this.innerHTML = ' '); }
|
||||
.icon-up-small { *zoom: expression( this.runtimeStyle['zoom'] = '1', this.innerHTML = ' '); }
|
||||
.icon-up-small { *zoom: expression( this.runtimeStyle['zoom'] = '1', this.innerHTML = ' '); }
|
||||
.icon-pin { *zoom: expression( this.runtimeStyle['zoom'] = '1', this.innerHTML = ' '); }
|
|
@ -130,4 +130,5 @@
|
|||
.icon-down-small { *zoom: expression( this.runtimeStyle['zoom'] = '1', this.innerHTML = ' '); }
|
||||
.icon-left-small { *zoom: expression( this.runtimeStyle['zoom'] = '1', this.innerHTML = ' '); }
|
||||
.icon-right-small { *zoom: expression( this.runtimeStyle['zoom'] = '1', this.innerHTML = ' '); }
|
||||
.icon-up-small { *zoom: expression( this.runtimeStyle['zoom'] = '1', this.innerHTML = ' '); }
|
||||
.icon-up-small { *zoom: expression( this.runtimeStyle['zoom'] = '1', this.innerHTML = ' '); }
|
||||
.icon-pin { *zoom: expression( this.runtimeStyle['zoom'] = '1', this.innerHTML = ' '); }
|
|
@ -1,10 +1,10 @@
|
|||
@font-face {
|
||||
font-family: 'ifont';
|
||||
src: url('../font/ifont.eot?54745533');
|
||||
src: url('../font/ifont.eot?54745533#iefix') format('embedded-opentype'),
|
||||
url('../font/ifont.woff?54745533') format('woff'),
|
||||
url('../font/ifont.ttf?54745533') format('truetype'),
|
||||
url('../font/ifont.svg?54745533#ifont') format('svg');
|
||||
src: url('../font/ifont.eot?612849');
|
||||
src: url('../font/ifont.eot?612849#iefix') format('embedded-opentype'),
|
||||
url('../font/ifont.woff?612849') format('woff'),
|
||||
url('../font/ifont.ttf?612849') format('truetype'),
|
||||
url('../font/ifont.svg?612849#ifont') format('svg');
|
||||
font-weight: normal;
|
||||
font-style: normal;
|
||||
}
|
||||
|
@ -14,7 +14,7 @@
|
|||
@media screen and (-webkit-min-device-pixel-ratio:0) {
|
||||
@font-face {
|
||||
font-family: 'ifont';
|
||||
src: url('../font/ifont.svg?54745533#ifont') format('svg');
|
||||
src: url('../font/ifont.svg?612849#ifont') format('svg');
|
||||
}
|
||||
}
|
||||
*/
|
||||
|
@ -174,4 +174,5 @@
|
|||
.icon-down-small:before { content: '\e875'; } /* '' */
|
||||
.icon-left-small:before { content: '\e876'; } /* '' */
|
||||
.icon-right-small:before { content: '\e877'; } /* '' */
|
||||
.icon-up-small:before { content: '\e878'; } /* '' */
|
||||
.icon-up-small:before { content: '\e878'; } /* '' */
|
||||
.icon-pin:before { content: '\e879'; } /* '' */
|
|
@ -229,11 +229,11 @@ body {
|
|||
}
|
||||
@font-face {
|
||||
font-family: 'ifont';
|
||||
src: url('./font/ifont.eot?11424534');
|
||||
src: url('./font/ifont.eot?11424534#iefix') format('embedded-opentype'),
|
||||
url('./font/ifont.woff?11424534') format('woff'),
|
||||
url('./font/ifont.ttf?11424534') format('truetype'),
|
||||
url('./font/ifont.svg?11424534#ifont') format('svg');
|
||||
src: url('./font/ifont.eot?91269362');
|
||||
src: url('./font/ifont.eot?91269362#iefix') format('embedded-opentype'),
|
||||
url('./font/ifont.woff?91269362') format('woff'),
|
||||
url('./font/ifont.ttf?91269362') format('truetype'),
|
||||
url('./font/ifont.svg?91269362#ifont') format('svg');
|
||||
font-weight: normal;
|
||||
font-style: normal;
|
||||
}
|
||||
|
@ -482,6 +482,7 @@ body {
|
|||
</div>
|
||||
<div class="row">
|
||||
<div title="Code: 0xe878" class="the-icons span3"><i class="demo-icon icon-up-small"></i> <span class="i-name">icon-up-small</span><span class="i-code">0xe878</span></div>
|
||||
<div title="Code: 0xe879" class="the-icons span3"><i class="demo-icon icon-pin"></i> <span class="i-name">icon-pin</span><span class="i-code">0xe879</span></div>
|
||||
</div>
|
||||
</div>
|
||||
<div class="container footer">Generated by <a href="http://fontello.com">fontello.com</a></div>
|
||||
|
|
|
@ -112,7 +112,7 @@ class DbConnection implements Selectable, Extensible, Updatable, Reducible, Insp
|
|||
/**
|
||||
* Getter for the Zend_Db_Adapter
|
||||
*
|
||||
* @return Zend_Db_Adapter_Abstract
|
||||
* @return \Zend_Db_Adapter_Abstract
|
||||
*/
|
||||
public function getDbAdapter()
|
||||
{
|
||||
|
|
|
@ -111,8 +111,8 @@ class AcknowledgeProblemCommandForm extends ObjectsCommandForm
|
|||
'label' => $this->translate('Sticky Acknowledgement'),
|
||||
'value' => true,
|
||||
'description' => $this->translate(
|
||||
'If you want the acknowledgement to disable notifications until the host or service recovers,'
|
||||
. ' check this option.'
|
||||
'If you want the acknowledgement to remain until the host or service recovers even if the host'
|
||||
. ' or service changes state, check this option.'
|
||||
)
|
||||
)
|
||||
),
|
||||
|
|
|
@ -8,14 +8,43 @@ if (in_array((int) $object->state, array(0, 99))) {
|
|||
}
|
||||
|
||||
if ($object->acknowledged): ?>
|
||||
<?php
|
||||
$acknowledgement = $object->acknowledgement;
|
||||
/** @var \Icinga\Module\Monitoring\Object\Acknowledgement $acknowledgement */
|
||||
?>
|
||||
<tr>
|
||||
<th><?= $this->translate('Acknowledged') ?></th>
|
||||
<td data-base-target="_self">
|
||||
<?php if (isset($removeAckForm)) { // Form is unset if the current user lacks the respective permission
|
||||
echo $removeAckForm;
|
||||
} else {
|
||||
echo '-';
|
||||
} ?>
|
||||
<ul class="inline-comments">
|
||||
<li class="comment-item">
|
||||
<h3>
|
||||
<?= sprintf(
|
||||
$this->translate('%s acknowledged %s'),
|
||||
'<span class="author">' . $this->escape($acknowledgement->getAuthor()) . '</span>',
|
||||
$this->timeAgo($acknowledgement->getEntryTime())
|
||||
) ?>
|
||||
<?php
|
||||
if ($acknowledgement->getSticky()) {
|
||||
echo $this->icon('pin', sprintf(
|
||||
$this->translate(
|
||||
'Acknowledgement remains until the %1$s recovers even if the %1$s changes state'
|
||||
),
|
||||
$object->getType(true)
|
||||
));
|
||||
}
|
||||
if (isset($removeAckForm)) {
|
||||
// Form is unset if the current user lacks the respective permission
|
||||
// Form is unset if the current user lacks the respective permission
|
||||
echo $removeAckForm;
|
||||
}
|
||||
?>
|
||||
</h3>
|
||||
<p>
|
||||
<span class="sr-only">(<?= $this->translate('Comment') ?>): </span>
|
||||
<?= nl2br($this->createTicketLinks($acknowledgement->getComment()), false) ?>
|
||||
</p>
|
||||
</li>
|
||||
</ul>
|
||||
</td>
|
||||
</tr>
|
||||
<?php else: ?>
|
||||
|
|
|
@ -25,8 +25,8 @@ class CommentQuery extends IdoQuery
|
|||
'comment_is_persistent' => 'c.comment_is_persistent',
|
||||
'comment_timestamp' => 'c.comment_timestamp',
|
||||
'comment_type' => 'c.comment_type',
|
||||
'object_type' => 'c.object_type',
|
||||
'instance_name' => 'c.instance_name'
|
||||
'instance_name' => 'c.instance_name',
|
||||
'object_type' => 'c.object_type'
|
||||
),
|
||||
'hosts' => array(
|
||||
'host_display_name' => 'c.host_display_name',
|
||||
|
|
|
@ -0,0 +1,215 @@
|
|||
<?php
|
||||
/* Icinga Web 2 | (c) 2013-2015 Icinga Development Team | GPLv2+ */
|
||||
|
||||
namespace Icinga\Module\Monitoring\Object;
|
||||
|
||||
use InvalidArgumentException;
|
||||
use Traversable;
|
||||
use Icinga\Util\String;
|
||||
|
||||
/**
|
||||
* Acknowledgement of a host or service incident
|
||||
*/
|
||||
class Acknowledgement
|
||||
{
|
||||
/**
|
||||
* Author of the acknowledgement
|
||||
*
|
||||
* @var string
|
||||
*/
|
||||
protected $author;
|
||||
|
||||
/**
|
||||
* Comment of the acknowledgement
|
||||
*
|
||||
* @var string
|
||||
*/
|
||||
protected $comment;
|
||||
|
||||
/**
|
||||
* Entry time of the acknowledgement
|
||||
*
|
||||
* @var int
|
||||
*/
|
||||
protected $entryTime;
|
||||
|
||||
/**
|
||||
* Expiration time of the acknowledgment
|
||||
*
|
||||
* @var int|null
|
||||
*/
|
||||
protected $expirationTime;
|
||||
|
||||
/**
|
||||
* Whether the acknowledgement is sticky
|
||||
*
|
||||
* Sticky acknowledgements suppress notifications until the host or service recovers
|
||||
*
|
||||
* @var bool
|
||||
*/
|
||||
protected $sticky = false;
|
||||
|
||||
/**
|
||||
* Create a new acknowledgement of a host or service incident
|
||||
*
|
||||
* @param array|object|Traversable $properties
|
||||
*
|
||||
* @throws InvalidArgumentException If the type of the given properties is invalid
|
||||
*/
|
||||
public function __construct($properties = null)
|
||||
{
|
||||
if ($properties !== null) {
|
||||
$this->setProperties($properties);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the author of the acknowledgement
|
||||
*
|
||||
* @return string
|
||||
*/
|
||||
public function getAuthor()
|
||||
{
|
||||
return $this->author;
|
||||
}
|
||||
|
||||
/**
|
||||
* Set the author of the acknowledgement
|
||||
*
|
||||
* @param string $author
|
||||
*
|
||||
* @return $this
|
||||
*/
|
||||
public function setAuthor($author)
|
||||
{
|
||||
$this->author = (string) $author;
|
||||
return $this;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the comment of the acknowledgement
|
||||
*
|
||||
* @return string
|
||||
*/
|
||||
public function getComment()
|
||||
{
|
||||
return $this->comment;
|
||||
}
|
||||
|
||||
/**
|
||||
* Set the comment of the acknowledgement
|
||||
*
|
||||
* @param string $comment
|
||||
*
|
||||
* @return $this
|
||||
*/
|
||||
public function setComment($comment)
|
||||
{
|
||||
$this->comment = (string) $comment;
|
||||
|
||||
return $this;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the entry time of the acknowledgement
|
||||
*
|
||||
* @return int
|
||||
*/
|
||||
public function getEntryTime()
|
||||
{
|
||||
return $this->entryTime;
|
||||
}
|
||||
|
||||
/**
|
||||
* Set the entry time of the acknowledgement
|
||||
*
|
||||
* @param int $entryTime
|
||||
*
|
||||
* @return $this
|
||||
*/
|
||||
public function setEntryTime($entryTime)
|
||||
{
|
||||
$this->entryTime = (int) $entryTime;
|
||||
|
||||
return $this;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the expiration time of the acknowledgement
|
||||
*
|
||||
* @return int|null
|
||||
*/
|
||||
public function getExpirationTime()
|
||||
{
|
||||
return $this->expirationTime;
|
||||
}
|
||||
|
||||
/**
|
||||
* Set the expiration time of the acknowledgement
|
||||
*
|
||||
* @param int|null $expirationTime Unix timestamp
|
||||
*
|
||||
* @return $this
|
||||
*/
|
||||
public function setExpirationTime($expirationTime = null)
|
||||
{
|
||||
$this->expirationTime = $expirationTime !== null ? (int) $expirationTime : null;
|
||||
|
||||
return $this;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get whether the acknowledgement is sticky
|
||||
*
|
||||
* @return bool
|
||||
*/
|
||||
public function getSticky()
|
||||
{
|
||||
return $this->sticky;
|
||||
}
|
||||
|
||||
/**
|
||||
* Set whether the acknowledgement is sticky
|
||||
*
|
||||
* @param bool $sticky
|
||||
*
|
||||
* @return $this
|
||||
*/
|
||||
public function setSticky($sticky = true)
|
||||
{
|
||||
$this->sticky = (bool) $sticky;
|
||||
return $this;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get whether the acknowledgement expires
|
||||
*
|
||||
* @return bool
|
||||
*/
|
||||
public function expires()
|
||||
{
|
||||
return $this->expirationTime !== null;
|
||||
}
|
||||
|
||||
/**
|
||||
* Set the properties of the acknowledgement
|
||||
*
|
||||
* @param array|object|Traversable $properties
|
||||
*
|
||||
* @return $this
|
||||
* @throws InvalidArgumentException If the type of the given properties is invalid
|
||||
*/
|
||||
public function setProperties($properties)
|
||||
{
|
||||
if (! is_array($properties) && ! is_object($properties) && ! $properties instanceof Traversable) {
|
||||
throw new InvalidArgumentException('Properties must be either an array or an instance of Traversable');
|
||||
}
|
||||
foreach ($properties as $name => $value) {
|
||||
$setter = 'set' . ucfirst(String::cname($name));
|
||||
if (method_exists($this, $setter)) {
|
||||
$this->$setter($value);
|
||||
}
|
||||
}
|
||||
return $this;
|
||||
}
|
||||
}
|
|
@ -93,6 +93,7 @@ class Host extends MonitoredObject
|
|||
'host_icon_image',
|
||||
'host_icon_image_alt',
|
||||
'host_acknowledged',
|
||||
'host_acknowledgement_type',
|
||||
'host_action_url',
|
||||
'host_active_checks_enabled',
|
||||
'host_active_checks_enabled_changed',
|
||||
|
|
|
@ -5,9 +5,9 @@ namespace Icinga\Module\Monitoring\Object;
|
|||
|
||||
use InvalidArgumentException;
|
||||
use Icinga\Application\Config;
|
||||
use Icinga\Exception\InvalidPropertyException;
|
||||
use Icinga\Data\Filter\Filter;
|
||||
use Icinga\Data\Filterable;
|
||||
use Icinga\Exception\InvalidPropertyException;
|
||||
use Icinga\Module\Monitoring\Backend\MonitoringBackend;
|
||||
use Icinga\Web\UrlParams;
|
||||
|
||||
|
@ -26,6 +26,13 @@ abstract class MonitoredObject implements Filterable
|
|||
*/
|
||||
const TYPE_SERVICE = 'service';
|
||||
|
||||
/**
|
||||
* Acknowledgement of the host or service if any
|
||||
*
|
||||
* @var object
|
||||
*/
|
||||
protected $acknowledgement;
|
||||
|
||||
/**
|
||||
* Backend to fetch object information from
|
||||
*
|
||||
|
@ -34,11 +41,60 @@ abstract class MonitoredObject implements Filterable
|
|||
protected $backend;
|
||||
|
||||
/**
|
||||
* Type of the Icinga object, i.e. 'host' or 'service'
|
||||
* Comments
|
||||
*
|
||||
* @var string
|
||||
* @var array
|
||||
*/
|
||||
protected $type;
|
||||
protected $comments;
|
||||
|
||||
/**
|
||||
* Custom variables
|
||||
*
|
||||
* @var array
|
||||
*/
|
||||
protected $customvars;
|
||||
|
||||
/**
|
||||
* Contact groups
|
||||
*
|
||||
* @var array
|
||||
*/
|
||||
protected $contactgroups;
|
||||
|
||||
/**
|
||||
* Contacts
|
||||
*
|
||||
* @var array
|
||||
*/
|
||||
protected $contacts;
|
||||
|
||||
/**
|
||||
* Downtimes
|
||||
*
|
||||
* @var array
|
||||
*/
|
||||
protected $downtimes;
|
||||
|
||||
/**
|
||||
* Event history
|
||||
*
|
||||
* @var \Icinga\Module\Monitoring\DataView\EventHistory
|
||||
*/
|
||||
protected $eventhistory;
|
||||
|
||||
/**
|
||||
* Filter
|
||||
*
|
||||
* @var Filter
|
||||
*/
|
||||
protected $filter;
|
||||
|
||||
/**
|
||||
* Host groups
|
||||
*
|
||||
* @var array
|
||||
*/
|
||||
protected $hostgroups;
|
||||
|
||||
/**
|
||||
* Prefix of the Icinga object, i.e. 'host_' or 'service_'
|
||||
|
@ -54,27 +110,6 @@ abstract class MonitoredObject implements Filterable
|
|||
*/
|
||||
protected $properties;
|
||||
|
||||
/**
|
||||
* Comments
|
||||
*
|
||||
* @var array
|
||||
*/
|
||||
protected $comments;
|
||||
|
||||
/**
|
||||
* Downtimes
|
||||
*
|
||||
* @var array
|
||||
*/
|
||||
protected $downtimes;
|
||||
|
||||
/**
|
||||
* Host groups
|
||||
*
|
||||
* @var array
|
||||
*/
|
||||
protected $hostgroups;
|
||||
|
||||
/**
|
||||
* Service groups
|
||||
*
|
||||
|
@ -83,32 +118,11 @@ abstract class MonitoredObject implements Filterable
|
|||
protected $servicegroups;
|
||||
|
||||
/**
|
||||
* Contacts
|
||||
* Type of the Icinga object, i.e. 'host' or 'service'
|
||||
*
|
||||
* @var array
|
||||
* @var string
|
||||
*/
|
||||
protected $contacts;
|
||||
|
||||
/**
|
||||
* Contact groups
|
||||
*
|
||||
* @var array
|
||||
*/
|
||||
protected $contactgroups;
|
||||
|
||||
/**
|
||||
* Custom variables
|
||||
*
|
||||
* @var array
|
||||
*/
|
||||
protected $customvars;
|
||||
|
||||
/**
|
||||
* Event history
|
||||
*
|
||||
* @var \Icinga\Module\Monitoring\DataView\EventHistory
|
||||
*/
|
||||
protected $eventhistory;
|
||||
protected $type;
|
||||
|
||||
/**
|
||||
* Stats
|
||||
|
@ -117,13 +131,6 @@ abstract class MonitoredObject implements Filterable
|
|||
*/
|
||||
protected $stats;
|
||||
|
||||
/**
|
||||
* Filter
|
||||
*
|
||||
* @var Filter
|
||||
*/
|
||||
protected $filter;
|
||||
|
||||
/**
|
||||
* Create a monitored object, i.e. host or service
|
||||
*
|
||||
|
@ -141,68 +148,64 @@ abstract class MonitoredObject implements Filterable
|
|||
*/
|
||||
abstract protected function getDataView();
|
||||
|
||||
public function applyFilter(Filter $filter)
|
||||
{
|
||||
$this->getFilter()->addFilter($filter);
|
||||
return $this;
|
||||
}
|
||||
/**
|
||||
* Get the notes for this monitored object
|
||||
*
|
||||
* @return string The notes as a string
|
||||
*/
|
||||
public abstract function getNotes();
|
||||
|
||||
public function setFilter(Filter $filter)
|
||||
{
|
||||
// Left out on purpose. Interface is deprecated.
|
||||
}
|
||||
|
||||
public function getFilter()
|
||||
{
|
||||
if ($this->filter === null) {
|
||||
$this->filter = Filter::matchAll();
|
||||
}
|
||||
return $this->filter;
|
||||
}
|
||||
/**
|
||||
* Get all note urls configured for this monitored object
|
||||
*
|
||||
* @return array All note urls as a string
|
||||
*/
|
||||
public abstract function getNotesUrls();
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
public function addFilter(Filter $filter)
|
||||
{
|
||||
// Left out on purpose. Interface is deprecated.
|
||||
}
|
||||
|
||||
public function where($condition, $value = null)
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
public function applyFilter(Filter $filter)
|
||||
{
|
||||
$this->getFilter()->addFilter($filter);
|
||||
|
||||
return $this;
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
public function getFilter()
|
||||
{
|
||||
if ($this->filter === null) {
|
||||
$this->filter = Filter::matchAll();
|
||||
}
|
||||
|
||||
return $this->filter;
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
public function setFilter(Filter $filter)
|
||||
{
|
||||
// Left out on purpose. Interface is deprecated.
|
||||
}
|
||||
|
||||
/**
|
||||
* Fetch the object's properties
|
||||
*
|
||||
* @return bool
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
public function fetch()
|
||||
public function where($condition, $value = null)
|
||||
{
|
||||
$this->properties = $this->getDataView()->applyFilter($this->getFilter())->getQuery()->fetchRow();
|
||||
if ($this->properties === false) {
|
||||
return false;
|
||||
}
|
||||
if (isset($this->properties->host_contacts)) {
|
||||
$this->contacts = array();
|
||||
foreach (preg_split('~,~', $this->properties->host_contacts) as $contact) {
|
||||
$this->contacts[] = (object) array(
|
||||
'contact_name' => $contact,
|
||||
'contact_alias' => $contact,
|
||||
'contact_email' => null,
|
||||
'contact_pager' => null,
|
||||
);
|
||||
}
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the type of the object
|
||||
*
|
||||
* @return string
|
||||
*/
|
||||
public function getType()
|
||||
{
|
||||
return $this->type;
|
||||
// Left out on purpose. Interface is deprecated.
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -222,15 +225,44 @@ abstract class MonitoredObject implements Filterable
|
|||
}
|
||||
|
||||
/**
|
||||
* Set the object's properties
|
||||
* Fetch the object's properties
|
||||
*
|
||||
* @param object $properties
|
||||
*
|
||||
* @return $this
|
||||
* @return bool
|
||||
*/
|
||||
public function setProperties($properties)
|
||||
public function fetch()
|
||||
{
|
||||
$this->properties = (object) $properties;
|
||||
$properties = $this->getDataView()->applyFilter($this->getFilter())->getQuery()->fetchRow();
|
||||
|
||||
if ($properties === false) {
|
||||
return false;
|
||||
}
|
||||
|
||||
if (isset($properties->host_contacts)) {
|
||||
$this->contacts = array();
|
||||
foreach (preg_split('~,~', $properties->host_contacts) as $contact) {
|
||||
$this->contacts[] = (object) array(
|
||||
'contact_name' => $contact,
|
||||
'contact_alias' => $contact,
|
||||
'contact_email' => null,
|
||||
'contact_pager' => null,
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
$this->properties = $properties;
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
/**
|
||||
* Fetch the object's acknowledgement
|
||||
*/
|
||||
public function fetchAcknowledgement()
|
||||
{
|
||||
if ($this->comments === null) {
|
||||
$this->fetchComments();
|
||||
}
|
||||
|
||||
return $this;
|
||||
}
|
||||
|
||||
|
@ -245,75 +277,108 @@ abstract class MonitoredObject implements Filterable
|
|||
$this->comments = array();
|
||||
return $this;
|
||||
}
|
||||
$comments = $this->backend->select()->from('comment', array(
|
||||
'id' => 'comment_internal_id',
|
||||
'timestamp' => 'comment_timestamp',
|
||||
'author' => 'comment_author_name',
|
||||
'comment' => 'comment_data',
|
||||
'type' => 'comment_type',
|
||||
))
|
||||
->where('comment_type', array('comment', 'ack'))
|
||||
|
||||
$commentsView = $this->backend->select()->from('comment', array(
|
||||
'author' => 'comment_author_name',
|
||||
'comment' => 'comment_data',
|
||||
'expiration' => 'comment_expiration',
|
||||
'id' => 'comment_internal_id',
|
||||
'timestamp' => 'comment_timestamp',
|
||||
'type' => 'comment_type'
|
||||
));
|
||||
if ($this->type === self::TYPE_SERVICE) {
|
||||
$commentsView
|
||||
->where('service_host_name', $this->host_name)
|
||||
->where('service_description', $this->service_description);
|
||||
} else {
|
||||
$commentsView->where('host_name', $this->host_name);
|
||||
}
|
||||
$commentsView
|
||||
->where('comment_type', array('ack', 'comment'))
|
||||
->where('object_type', $this->type);
|
||||
if ($this->type === self::TYPE_SERVICE) {
|
||||
$comments
|
||||
->where('service_host_name', $this->host_name)
|
||||
->where('service_description', $this->service_description);
|
||||
} else {
|
||||
$comments->where('host_name', $this->host_name);
|
||||
|
||||
$comments = $commentsView->fetchAll();
|
||||
|
||||
if ((bool) $this->properties->{$this->prefix . 'acknowledged'}) {
|
||||
$ackCommentIdx = null;
|
||||
|
||||
foreach ($comments as $i => $comment) {
|
||||
if ($comment->type === 'ack') {
|
||||
$this->acknowledgement = new Acknowledgement(array(
|
||||
'author' => $comment->author,
|
||||
'comment' => $comment->comment,
|
||||
'entry_time' => $comment->timestamp,
|
||||
'expiration_time' => $comment->expiration,
|
||||
'sticky' => (int) $this->properties->{$this->prefix . 'acknowledgement_type'} === 2
|
||||
));
|
||||
$ackCommentIdx = $i;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if ($ackCommentIdx !== null) {
|
||||
unset($comments[$ackCommentIdx]);
|
||||
}
|
||||
}
|
||||
$this->comments = $comments->getQuery()->fetchAll();
|
||||
|
||||
$this->comments = $comments;
|
||||
|
||||
return $this;
|
||||
}
|
||||
|
||||
/**
|
||||
* Fetch the object's downtimes
|
||||
* Fetch the object's contact groups
|
||||
*
|
||||
* @return $this
|
||||
*/
|
||||
public function fetchDowntimes()
|
||||
public function fetchContactgroups()
|
||||
{
|
||||
$downtimes = $this->backend->select()->from('downtime', array(
|
||||
'id' => 'downtime_internal_id',
|
||||
'objecttype' => 'object_type',
|
||||
'comment' => 'downtime_comment',
|
||||
'author_name' => 'downtime_author_name',
|
||||
'start' => 'downtime_start',
|
||||
'scheduled_start' => 'downtime_scheduled_start',
|
||||
'scheduled_end' => 'downtime_scheduled_end',
|
||||
'end' => 'downtime_end',
|
||||
'duration' => 'downtime_duration',
|
||||
'is_flexible' => 'downtime_is_flexible',
|
||||
'is_fixed' => 'downtime_is_fixed',
|
||||
'is_in_effect' => 'downtime_is_in_effect',
|
||||
'entry_time' => 'downtime_entry_time'
|
||||
))
|
||||
->where('object_type', $this->type)
|
||||
->order('downtime_is_in_effect', 'DESC')
|
||||
->order('downtime_scheduled_start', 'ASC');
|
||||
if ($this->backend->is('livestatus')) {
|
||||
$this->contactgroups = array();
|
||||
return $this;
|
||||
}
|
||||
|
||||
$contactsGroups = $this->backend->select()->from('contactgroup', array(
|
||||
'contactgroup_name',
|
||||
'contactgroup_alias'
|
||||
));
|
||||
if ($this->type === self::TYPE_SERVICE) {
|
||||
$downtimes
|
||||
$contactsGroups
|
||||
->where('service_host_name', $this->host_name)
|
||||
->where('service_description', $this->service_description);
|
||||
} else {
|
||||
$downtimes
|
||||
->where('host_name', $this->host_name);
|
||||
$contactsGroups->where('host_name', $this->host_name);
|
||||
}
|
||||
$this->downtimes = $downtimes->getQuery()->fetchAll();
|
||||
$this->contactgroups = $contactsGroups->applyFilter($this->getFilter())->getQuery()->fetchAll();
|
||||
return $this;
|
||||
}
|
||||
|
||||
/**
|
||||
* Fetch the object's host groups
|
||||
* Fetch the object's contacts
|
||||
*
|
||||
* @return $this
|
||||
*/
|
||||
public function fetchHostgroups()
|
||||
public function fetchContacts()
|
||||
{
|
||||
$this->hostgroups = $this->backend->select()
|
||||
->from('hostgroup', array('hostgroup_name', 'hostgroup_alias'))
|
||||
->where('host_name', $this->host_name)
|
||||
->applyFilter($this->getFilter())
|
||||
->fetchPairs();
|
||||
if ($this->backend->is('livestatus')) {
|
||||
$this->contacts = array();
|
||||
return $this;
|
||||
}
|
||||
|
||||
$contacts = $this->backend->select()->from('contact', array(
|
||||
'contact_name',
|
||||
'contact_alias',
|
||||
'contact_email',
|
||||
'contact_pager',
|
||||
));
|
||||
if ($this->type === self::TYPE_SERVICE) {
|
||||
$contacts
|
||||
->where('service_host_name', $this->host_name)
|
||||
->where('service_description', $this->service_description);
|
||||
} else {
|
||||
$contacts->where('host_name', $this->host_name);
|
||||
}
|
||||
$this->contacts = $contacts->applyFilter($this->getFilter())->getQuery()->fetchAll();
|
||||
return $this;
|
||||
}
|
||||
|
||||
|
@ -372,74 +437,39 @@ abstract class MonitoredObject implements Filterable
|
|||
}
|
||||
|
||||
/**
|
||||
* Fetch the object's contacts
|
||||
* Fetch the object's downtimes
|
||||
*
|
||||
* @return $this
|
||||
*/
|
||||
public function fetchContacts()
|
||||
public function fetchDowntimes()
|
||||
{
|
||||
if ($this->backend->is('livestatus')) {
|
||||
$this->contacts = array();
|
||||
return $this;
|
||||
}
|
||||
|
||||
$contacts = $this->backend->select()->from('contact', array(
|
||||
'contact_name',
|
||||
'contact_alias',
|
||||
'contact_email',
|
||||
'contact_pager',
|
||||
));
|
||||
$downtimes = $this->backend->select()->from('downtime', array(
|
||||
'id' => 'downtime_internal_id',
|
||||
'objecttype' => 'object_type',
|
||||
'comment' => 'downtime_comment',
|
||||
'author_name' => 'downtime_author_name',
|
||||
'start' => 'downtime_start',
|
||||
'scheduled_start' => 'downtime_scheduled_start',
|
||||
'scheduled_end' => 'downtime_scheduled_end',
|
||||
'end' => 'downtime_end',
|
||||
'duration' => 'downtime_duration',
|
||||
'is_flexible' => 'downtime_is_flexible',
|
||||
'is_fixed' => 'downtime_is_fixed',
|
||||
'is_in_effect' => 'downtime_is_in_effect',
|
||||
'entry_time' => 'downtime_entry_time'
|
||||
))
|
||||
->where('object_type', $this->type)
|
||||
->order('downtime_is_in_effect', 'DESC')
|
||||
->order('downtime_scheduled_start', 'ASC');
|
||||
if ($this->type === self::TYPE_SERVICE) {
|
||||
$contacts
|
||||
$downtimes
|
||||
->where('service_host_name', $this->host_name)
|
||||
->where('service_description', $this->service_description);
|
||||
} else {
|
||||
$contacts->where('host_name', $this->host_name);
|
||||
$downtimes
|
||||
->where('host_name', $this->host_name);
|
||||
}
|
||||
$this->contacts = $contacts->applyFilter($this->getFilter())->getQuery()->fetchAll();
|
||||
return $this;
|
||||
}
|
||||
|
||||
/**
|
||||
* Fetch the object's service groups
|
||||
*
|
||||
* @return $this
|
||||
*/
|
||||
public function fetchServicegroups()
|
||||
{
|
||||
$this->servicegroups = $this->backend->select()
|
||||
->from('servicegroup', array('servicegroup_name', 'servicegroup_alias'))
|
||||
->where('host_name', $this->host_name)
|
||||
->where('service_description', $this->service_description)
|
||||
->applyFilter($this->getFilter())
|
||||
->fetchPairs();
|
||||
return $this;
|
||||
}
|
||||
|
||||
/**
|
||||
* Fetch the object's contact groups
|
||||
*
|
||||
* @return $this
|
||||
*/
|
||||
public function fetchContactgroups()
|
||||
{
|
||||
if ($this->backend->is('livestatus')) {
|
||||
$this->contactgroups = array();
|
||||
return $this;
|
||||
}
|
||||
|
||||
$contactsGroups = $this->backend->select()->from('contactgroup', array(
|
||||
'contactgroup_name',
|
||||
'contactgroup_alias'
|
||||
));
|
||||
if ($this->type === self::TYPE_SERVICE) {
|
||||
$contactsGroups
|
||||
->where('service_host_name', $this->host_name)
|
||||
->where('service_description', $this->service_description);
|
||||
} else {
|
||||
$contactsGroups->where('host_name', $this->host_name);
|
||||
}
|
||||
$this->contactgroups = $contactsGroups->applyFilter($this->getFilter())->getQuery()->fetchAll();
|
||||
$this->downtimes = $downtimes->getQuery()->fetchAll();
|
||||
return $this;
|
||||
}
|
||||
|
||||
|
@ -477,6 +507,37 @@ abstract class MonitoredObject implements Filterable
|
|||
return $this;
|
||||
}
|
||||
|
||||
/**
|
||||
* Fetch the object's host groups
|
||||
*
|
||||
* @return $this
|
||||
*/
|
||||
public function fetchHostgroups()
|
||||
{
|
||||
$this->hostgroups = $this->backend->select()
|
||||
->from('hostgroup', array('hostgroup_name', 'hostgroup_alias'))
|
||||
->where('host_name', $this->host_name)
|
||||
->applyFilter($this->getFilter())
|
||||
->fetchPairs();
|
||||
return $this;
|
||||
}
|
||||
|
||||
/**
|
||||
* Fetch the object's service groups
|
||||
*
|
||||
* @return $this
|
||||
*/
|
||||
public function fetchServicegroups()
|
||||
{
|
||||
$this->servicegroups = $this->backend->select()
|
||||
->from('servicegroup', array('servicegroup_name', 'servicegroup_alias'))
|
||||
->where('host_name', $this->host_name)
|
||||
->where('service_description', $this->service_description)
|
||||
->applyFilter($this->getFilter())
|
||||
->fetchPairs();
|
||||
return $this;
|
||||
}
|
||||
|
||||
/**
|
||||
* Fetch stats
|
||||
*
|
||||
|
@ -504,6 +565,74 @@ abstract class MonitoredObject implements Filterable
|
|||
return $this;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get all action urls configured for this monitored object
|
||||
*
|
||||
* @return array All note urls as a string
|
||||
*/
|
||||
public function getActionUrls()
|
||||
{
|
||||
return $this->resolveAllStrings(
|
||||
MonitoredObject::parseAttributeUrls($this->action_url)
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the type of the object
|
||||
*
|
||||
* @param bool $translate
|
||||
*
|
||||
* @return string
|
||||
*/
|
||||
public function getType($translate = false)
|
||||
{
|
||||
if ($translate !== false) {
|
||||
switch ($this->type) {
|
||||
case self::TYPE_HOST:
|
||||
$type = mt('montiroing', 'host');
|
||||
break;
|
||||
case self::TYPE_SERVICE:
|
||||
$type = mt('monitoring', 'service');
|
||||
break;
|
||||
default:
|
||||
throw new InvalidArgumentException('Invalid type ' . $this->type);
|
||||
}
|
||||
} else {
|
||||
$type = $this->type;
|
||||
}
|
||||
return $type;
|
||||
}
|
||||
|
||||
/**
|
||||
* Parse the content of the action_url or notes_url attributes
|
||||
*
|
||||
* Find all occurences of http links, separated by whitespaces and quoted
|
||||
* by single or double-ticks.
|
||||
*
|
||||
* @link http://docs.icinga.org/latest/de/objectdefinitions.html
|
||||
*
|
||||
* @param string $urlString A string containing one or more urls
|
||||
* @return array Array of urls as strings
|
||||
*/
|
||||
public static function parseAttributeUrls($urlString)
|
||||
{
|
||||
if (empty($urlString)) {
|
||||
return array();
|
||||
}
|
||||
$links = array();
|
||||
if (strpos($urlString, "' ") === false) {
|
||||
$links[] = $urlString;
|
||||
} else {
|
||||
// parse notes-url format
|
||||
foreach (explode("' ", $urlString) as $url) {
|
||||
$url = strpos($url, "'") === 0 ? substr($url, 1) : $url;
|
||||
$url = strrpos($url, "'") === strlen($url) - 1 ? substr($url, 0, strlen($url) - 1) : $url;
|
||||
$links[] = $url;
|
||||
}
|
||||
}
|
||||
return $links;
|
||||
}
|
||||
|
||||
/**
|
||||
* Fetch all available data of the object
|
||||
*
|
||||
|
@ -513,16 +642,56 @@ abstract class MonitoredObject implements Filterable
|
|||
{
|
||||
$this
|
||||
->fetchComments()
|
||||
->fetchContacts()
|
||||
->fetchContactgroups()
|
||||
->fetchContacts()
|
||||
->fetchCustomvars()
|
||||
->fetchDowntimes();
|
||||
|
||||
// Call fetchHostgroups or fetchServicegroups depending on the object's type
|
||||
$fetchGroups = 'fetch' . ucfirst($this->type) . 'groups';
|
||||
$this->$fetchGroups();
|
||||
|
||||
return $this;
|
||||
}
|
||||
|
||||
/**
|
||||
* Resolve macros in all given strings in the current object context
|
||||
*
|
||||
* @param array $strs An array of urls as string
|
||||
*
|
||||
* @return array
|
||||
*/
|
||||
protected function resolveAllStrings(array $strs)
|
||||
{
|
||||
foreach ($strs as $i => $str) {
|
||||
$strs[$i] = Macro::resolveMacros($str, $this);
|
||||
}
|
||||
return $strs;
|
||||
}
|
||||
|
||||
/**
|
||||
* Set the object's properties
|
||||
*
|
||||
* @param object $properties
|
||||
*
|
||||
* @return $this
|
||||
*/
|
||||
public function setProperties($properties)
|
||||
{
|
||||
$this->properties = (object) $properties;
|
||||
return $this;
|
||||
}
|
||||
|
||||
public function __isset($name)
|
||||
{
|
||||
if (property_exists($this->properties, $name)) {
|
||||
return isset($this->properties->$name);
|
||||
} elseif (property_exists($this, $name)) {
|
||||
return isset($this->$name);
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
public function __get($name)
|
||||
{
|
||||
if (property_exists($this->properties, $name)) {
|
||||
|
@ -543,16 +712,6 @@ abstract class MonitoredObject implements Filterable
|
|||
throw new InvalidPropertyException('Can\'t access property \'%s\'. Property does not exist.', $name);
|
||||
}
|
||||
|
||||
public function __isset($name)
|
||||
{
|
||||
if (property_exists($this->properties, $name)) {
|
||||
return isset($this->properties->$name);
|
||||
} elseif (property_exists($this, $name)) {
|
||||
return isset($this->$name);
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
/**
|
||||
* @deprecated
|
||||
*/
|
||||
|
@ -565,73 +724,4 @@ abstract class MonitoredObject implements Filterable
|
|||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
/**
|
||||
* The notes for this monitored object
|
||||
*
|
||||
* @return string The notes as a string
|
||||
*/
|
||||
public abstract function getNotes();
|
||||
|
||||
/**
|
||||
* Get all note urls configured for this monitored object
|
||||
*
|
||||
* @return array All note urls as a string
|
||||
*/
|
||||
public abstract function getNotesUrls();
|
||||
|
||||
/**
|
||||
* Get all action urls configured for this monitored object
|
||||
*
|
||||
* @return array All note urls as a string
|
||||
*/
|
||||
public function getActionUrls()
|
||||
{
|
||||
return $this->resolveAllStrings(
|
||||
MonitoredObject::parseAttributeUrls($this->action_url)
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* Resolve macros in all given strings in the current object context
|
||||
*
|
||||
* @param array $strs An array of urls as string
|
||||
* @return type
|
||||
*/
|
||||
protected function resolveAllStrings(array $strs)
|
||||
{
|
||||
foreach ($strs as $i => $str) {
|
||||
$strs[$i] = Macro::resolveMacros($str, $this);
|
||||
}
|
||||
return $strs;
|
||||
}
|
||||
|
||||
/**
|
||||
* Parse the content of the action_url or notes_url attributes
|
||||
*
|
||||
* Find all occurences of http links, separated by whitespaces and quoted
|
||||
* by single or double-ticks.
|
||||
*
|
||||
* @link http://docs.icinga.org/latest/de/objectdefinitions.html
|
||||
*
|
||||
* @param string $urlString A string containing one or more urls
|
||||
* @return array Array of urls as strings
|
||||
*/
|
||||
public static function parseAttributeUrls($urlString)
|
||||
{
|
||||
if (empty($urlString)) {
|
||||
return array();
|
||||
}
|
||||
if (strpos($urlString, "' ") === false) {
|
||||
$links[] = $urlString;
|
||||
} else {
|
||||
// parse notes-url format
|
||||
foreach (explode("' ", $urlString) as $url) {
|
||||
$url = strpos($url, "'") === 0 ? substr($url, 1) : $url;
|
||||
$url = strrpos($url, "'") === strlen($url) - 1 ? substr($url, 0, strlen($url) - 1) : $url;
|
||||
$links[] = $url;
|
||||
}
|
||||
}
|
||||
return $links;
|
||||
}
|
||||
}
|
||||
|
|
|
@ -124,6 +124,7 @@ class Service extends MonitoredObject
|
|||
'service_icon_image',
|
||||
'service_icon_image_alt',
|
||||
'service_acknowledged',
|
||||
'service_acknowledgement_type',
|
||||
'service_action_url',
|
||||
'service_active_checks_enabled',
|
||||
'service_active_checks_enabled_changed',
|
||||
|
|
Binary file not shown.
|
@ -111,7 +111,7 @@
|
|||
<glyph glyph-name="host" unicode="" d="m232 136q-37 0-63 26t-26 63v393q0 37 26 63t63 26h607q37 0 63-26t27-63v-393q0-37-27-63t-63-26h-607z m-18 482v-393q0-7 6-13t12-5h607q8 0 13 5t5 13v393q0 7-5 12t-13 6h-607q-7 0-12-6t-6-12z m768-518h89v-54q0-22-26-37t-63-16h-893q-36 0-63 16t-26 37v54h982z m-402-54q9 0 9 9t-9 9h-89q-9 0-9-9t9-9h89z" horiz-adv-x="1071.4" />
|
||||
<glyph glyph-name="thumbs-up" unicode="" d="m143 100q0 15-11 25t-25 11-25-11-11-25 11-25 25-11 25 11 11 25z m643 321q0 29-22 50t-50 22h-196q0 32 27 89t26 89q0 55-17 81t-72 27q-14-15-21-48t-17-70-33-61q-13-13-43-51-2-3-13-17t-18-22-19-24-22-25-22-19-22-16-20-5h-18v-357h18q7 0 18-1t18-4 21-6 20-7 20-7 16-5q118-41 191-41h67q107 0 107 93 0 15-2 31 16 9 26 30t10 41-10 38q29 28 29 67 0 13-5 31t-14 26q18 1 30 26t12 45z m71 1q0-50-27-91 5-18 5-38 0-43-21-81 1-12 1-24 0-56-33-99 0-78-48-123t-126-45h-72q-54 0-106 13t-121 36q-65 23-77 23h-161q-29 0-50 21t-21 50v357q0 30 21 51t50 21h153q20 13 77 86 32 42 60 72 13 14 19 47t17 71 35 60q22 21 50 21 47 0 84-18t57-57 20-104q0-51-27-107h98q58 0 101-42t42-100z" horiz-adv-x="857.1" />
|
||||
<glyph glyph-name="thumbs-down" unicode="" d="m143 600q0 15-11 25t-25 11-25-11-11-25 11-25 25-11 25 11 11 25z m643-321q0 19-12 45t-30 26q8 10 14 27t5 30q0 39-29 67 10 18 10 38t-10 41-26 30q2 16 2 31 0 47-27 70t-76 23h-71q-73 0-191-41-3-1-16-6t-20-7-20-6-21-6-18-4-18-1h-18v-358h18q9 0 20-5t22-15 22-19 22-25 19-24 18-23 13-16q30-38 43-51 23-24 33-61t17-70 21-48q54 0 72 27t17 81q0 32-26 89t-27 89h196q28 0 50 22t22 49z m71-1q0-57-42-100t-101-42h-98q27-55 27-107 0-66-20-104-19-39-57-57t-84-18q-28 0-50 21-19 18-30 45t-14 51-10 47-17 36q-27 28-60 71-57 73-77 86h-153q-29 0-50 21t-21 51v357q0 29 21 50t50 21h161q12 0 77 22 72 25 125 37t111 13h63q78 0 126-45t48-120v-3q33-43 33-99 0-13-1-24 21-38 21-81 0-20-5-38 27-41 27-91z" horiz-adv-x="857.1" />
|
||||
<glyph glyph-name="spinner" unicode="" d="m277 100q0-33-24-57t-57-23q-33 0-56 23t-24 57 24 57 56 23q33 0 57-23t24-57z m241-107q0-30-21-51t-51-21-50 21-21 51 21 50 50 21 51-21 21-50z m-339 357q0-37-27-63t-63-26-63 26-26 63 26 63 63 26 63-26 27-63z m580-250q0-26-18-44t-45-18-44 18-18 44 18 44 44 19 45-19 18-44z m-464 500q0-41-29-69t-70-29-69 29-29 69 29 69 69 29 70-29 29-69z m259 107q0-45-32-76t-76-31-75 31-32 76 32 76 75 31 76-31 32-76z m303-357q0-22-15-38t-38-16-38 16-16 38 16 38 38 16 38-16 15-38z m-116 250q0-18-13-32t-32-13-31 13-13 32 13 31 31 14 32-14 13-31z" horiz-adv-x="875" />
|
||||
<glyph glyph-name="spinner" unicode="" d="m294 72q0-29-21-50t-51-21q-29 0-50 21t-21 50q0 30 21 51t50 21 51-21 21-51z m277-115q0-29-20-50t-51-21-50 21-21 50 21 51 50 21 51-21 20-51z m-392 393q0-30-21-50t-51-21-50 21-21 50 21 51 50 20 51-20 21-51z m670-278q0-29-21-50t-50-21q-30 0-51 21t-21 50 21 51 51 21 50-21 21-51z m-538 556q0-37-26-63t-63-26-63 26-26 63 26 63 63 26 63-26 26-63z m653-278q0-30-21-50t-50-21-51 21-21 50 21 51 51 20 50-20 21-51z m-357 393q0-45-31-76t-76-31-76 31-31 76 31 76 76 31 76-31 31-76z m296-115q0-52-37-89t-88-36q-52 0-89 36t-36 89q0 51 36 88t89 37q51 0 88-37t37-88z" horiz-adv-x="1000" />
|
||||
<glyph glyph-name="attach" unicode="" d="m783 77q0-65-44-109t-109-44q-75 0-131 55l-434 434q-63 64-63 151 0 88 62 150t150 62q88 0 152-63l338-338q5-5 5-12 0-9-17-26t-26-17q-7 0-13 5l-338 339q-44 43-101 43-59 0-100-42t-40-101q0-58 42-101l433-433q35-35 81-35 36 0 59 23t24 59q0 46-36 81l-324 324q-14 14-33 14-16 0-27-11t-11-27q0-18 14-33l229-228q6-6 6-13 0-9-18-26t-26-17q-7 0-12 5l-229 229q-35 34-35 83 0 46 32 78t77 32q49 0 83-36l325-324q55-54 55-131z" horiz-adv-x="785.7" />
|
||||
<glyph glyph-name="keyboard" unicode="" d="m214 198v-53q0-9-9-9h-53q-9 0-9 9v53q0 9 9 9h53q9 0 9-9z m72 143v-53q0-9-9-9h-125q-9 0-9 9v53q0 9 9 9h125q9 0 9-9z m-72 143v-54q0-9-9-9h-53q-9 0-9 9v54q0 9 9 9h53q9 0 9-9z m572-286v-53q0-9-9-9h-482q-9 0-9 9v53q0 9 9 9h482q9 0 9-9z m-357 143v-53q0-9-9-9h-54q-9 0-9 9v53q0 9 9 9h54q9 0 9-9z m-72 143v-54q0-9-9-9h-53q-9 0-9 9v54q0 9 9 9h53q9 0 9-9z m214-143v-53q0-9-8-9h-54q-9 0-9 9v53q0 9 9 9h54q8 0 8-9z m-71 143v-54q0-9-9-9h-53q-9 0-9 9v54q0 9 9 9h53q9 0 9-9z m214-143v-53q0-9-9-9h-53q-9 0-9 9v53q0 9 9 9h53q9 0 9-9z m215-143v-53q0-9-9-9h-54q-9 0-9 9v53q0 9 9 9h54q9 0 9-9z m-286 286v-54q0-9-9-9h-54q-9 0-9 9v54q0 9 9 9h54q9 0 9-9z m143 0v-54q0-9-9-9h-54q-9 0-9 9v54q0 9 9 9h54q9 0 9-9z m143 0v-196q0-9-9-9h-125q-9 0-9 9v53q0 9 9 9h62v134q0 9 9 9h54q9 0 9-9z m71-420v500h-929v-500h929z m71 500v-500q0-29-21-50t-50-21h-929q-29 0-50 21t-21 50v500q0 30 21 51t50 21h929q30 0 50-21t21-51z" horiz-adv-x="1071.4" />
|
||||
<glyph glyph-name="menu" unicode="" d="m857 100v-71q0-15-10-25t-26-11h-785q-15 0-25 11t-11 25v71q0 15 11 25t25 11h785q15 0 26-11t10-25z m0 286v-72q0-14-10-25t-26-10h-785q-15 0-25 10t-11 25v72q0 14 11 25t25 10h785q15 0 26-10t10-25z m0 285v-71q0-15-10-25t-26-11h-785q-15 0-25 11t-11 25v71q0 15 11 26t25 10h785q15 0 26-10t10-26z" horiz-adv-x="857.1" />
|
||||
|
@ -123,6 +123,11 @@
|
|||
<glyph glyph-name="beaker" unicode="" d="m852 42q31-50 12-85t-78-36h-643q-59 0-79 36t12 85l281 442v223h-36q-14 0-25 11t-10 25 10 25 25 11h286q15 0 25-11t11-25-11-25-25-11h-36v-223z m-435 405l-151-240h397l-152 240-11 17v243h-71v-243z" horiz-adv-x="928.6" />
|
||||
<glyph glyph-name="magic" unicode="" d="m664 526l164 163-60 60-164-164z m249 163q0-15-10-25l-717-718q-10-10-25-10t-25 10l-111 111q-10 10-10 25t10 25l718 718q10 10 25 10t25-10l110-111q10-10 10-25z m-753 106l54-16-54-17-17-55-17 55-55 17 55 16 17 55z m195-90l109-34-109-33-34-109-33 109-109 33 109 34 33 109z m519-267l55-17-55-16-17-55-17 55-54 16 54 17 17 55z m-357 357l54-16-54-17-17-55-17 55-54 17 54 16 17 55z" horiz-adv-x="928.6" />
|
||||
<glyph glyph-name="spin6" unicode="" d="m855 9c-189-190-520-172-705 13-190 190-200 494-28 695 11 13 21 26 35 34 36 23 85 18 117-13 30-31 35-76 16-112-5-9-9-15-16-22-140-151-145-379-8-516 153-153 407-121 542 34 106 122 142 297 77 451-83 198-305 291-510 222l0 1c236 82 492-24 588-252 71-167 37-355-72-493-11-15-23-29-36-42z" horiz-adv-x="1000" />
|
||||
<glyph glyph-name="down-small" unicode="" d="m505 346q15-15 15-37t-15-37l-245-245-245 245q-15 15-15 37t15 37 37 15 37-15l120-119 0 395q0 21 15 36t36 15 37-15 16-36l0-395 120 119q15 15 36 15t36-15z" horiz-adv-x="520" />
|
||||
<glyph glyph-name="left-small" unicode="" d="m595 403q21 0 36-16t15-37-15-37-36-15l-395 0 119-119q15-15 15-37t-15-37-36-15q-23 0-38 15l-245 245 245 245q15 15 37 15t37-15 15-37-15-37l-119-118 395 0z" horiz-adv-x="646" />
|
||||
<glyph glyph-name="right-small" unicode="" d="m328 595q15 15 36 15t37-15l245-245-245-245q-15-15-36-15-22 0-37 15t-15 37 15 37l120 119-395 0q-22 0-37 15t-16 37 16 37 37 16l395 0-120 118q-15 15-15 37t15 37z" horiz-adv-x="646" />
|
||||
<glyph glyph-name="up-small" unicode="" d="m260 673l245-245q15-15 15-37t-15-37-36-15-36 15l-120 120 0-395q0-21-16-37t-37-15-36 15-15 37l0 395-120-120q-15-15-37-15t-37 15-15 37 15 37z" horiz-adv-x="520" />
|
||||
<glyph glyph-name="pin" unicode="" d="m573 37q0-23-15-38t-37-15q-21 0-37 16l-169 169-315-236 236 315-168 169q-24 23-12 56 14 32 48 32 157 0 270 57 90 45 151 171 9 24 36 32t50-13l208-209q21-23 14-50t-32-36q-127-63-172-152-56-110-56-268z" horiz-adv-x="834" />
|
||||
</font>
|
||||
</defs>
|
||||
</svg>
|
Before Width: | Height: | Size: 53 KiB After Width: | Height: | Size: 54 KiB |
Binary file not shown.
Binary file not shown.
Loading…
Reference in New Issue