phplib/Page.php

Summary

Maintainability
A
2 hrs
Test Coverage
<?php

namespace Yagd;

class Page
{

    protected $config = [];
    protected $defaultTimes = [
        '1hour', '4hours', '12hours',
        '1day', '2days',
        '1week',
        '1month', '3months', '6months',
        '1year'
    ];
    protected $defaultTime = "4hours";
    protected $selectBox = null;

    public function __construct($config)
    {
        $this->config = $config;
        if (!isset($this->config["graphite"]["hidelegend"])) {
            $this->config["graphite"]["hidelegend"] = true;
        }
        $this->requestURI = filter_input(INPUT_SERVER, 'REQUEST_URI');
        $this->from = filter_input(INPUT_GET, 'from');
        if (!isset($this->from)) {
            $this->from = "-" . $this->defaultTime;
        }
    }

    /**
     * helper function to build a generic row of Graphite img tag metrics
     *
     * Parameters
     *  $metrics - array of Graphite metrics
     *
     * Returns the HTML for the graphs
     */
    public function buildPageForMetrics($metrics)
    {
        $ret = '<div class="row">';
        foreach ($metrics as $metric) {
            $graph = new GraphiteGraph(
                $this->config['graphite']['host'],
                $this->from,
                null,
                $this->config['graphite']['hidelegend']
            );

            $ret .= '<div class="col-md-4">';
            $ret .= $graph->buildGraphImgTag($metric);
            $ret .= '</div>';
        }
        $ret .= '</div>';
        return $ret;
    }

    /**
     * helper function to generically render a full page
     *
     * Parameters:
     *  $metrics - array of graphite metrics to render
     */
    public function renderFullPageWithMetrics($metrics)
    {
        print $this->getHeader();
        print $this->buildPageForMetrics($metrics);
        print $this->getFooter();
    }

    /**
     * helper function to return bootstrap compatible attribute data if the
     * current URI matches the passed in one
     *
     * Parameters
     *  $requestUri - URI to match
     *
     * Returns class='active' or the empty string
     */
    public function getActiveClassIfRequestMatches($requestUri)
    {
        $ret = "";
        if ($this->requestURI === $requestUri) {
            $ret = " class='active'";
        }

        return $ret;
    }

    /**
     * get a select box for an array of times
     *
     * Parameters
     *  $times - array of times
     *
     * Returns the HTML for the full select box as a string
     */
    public function getTimeSelectBox($times = null)
    {

        if (is_null($times)) {
            $times = $this->defaultTimes;
        }

        $ret = "";
        $ret .= "<form method='get' action='{$this->requestURI}' ";
        $ret .= "style='margin-top: 15px'class='pull-right'>";
        $ret .= "<select name='from' onchange='this.form.submit()'>" . PHP_EOL;
        foreach ($times as $timefrom) {
            $current = $this->from ?: "-{$this->defaultTime}";
            $selected = ($current == "-${timefrom}") ? " selected" : "";
            $ret .= "<option ";
            $ret .= "value='-{$timefrom}'{$selected}>";
            $ret .= "{$timefrom}</option>";
            $ret .= PHP_EOL;
        }

        $ret .= "</select> </form>";

        return $ret;

    }

    /**
     * Set the select box property
     *
     * Parameters
     *  $select_box - HTML for the select box
     */
    public function setSelectBox($selectBox)
    {
        $this->selectBox = $selectBox;
    }

    /**
     * Set the requestURI property. This is probably only useful for unit
     * testing.
     *
     * Parameters
     *  $requestUri - URI to set the requestURI to
     */
    public function setRequestURI($requestURI)
    {
        $this->requestURI = $requestURI;
    }


    /**
     * Get the Yagd HTML header for a page. This can be passed in a couple of
     * parameters to get a customized page. However by default all parameters
     * are taken from the Page object configuration.
     *
     * Parameters
     *  $title     - title of the current page
     *  $nav_items - items to show in the nav bar
     *  $selectbox - select box HTML to show
     *  $times     - array of times for the drop down
     *
     *  Returns the header data as a string
     */
    public function getHeader(
        $title = null,
        $navItems = [],
        $selectbox = null,
        $times = null
    ) {

        if (is_null($title)) {
            $title = $this->config["title"];
        }
        $navBar = '<li' . $this->getActiveClassIfRequestMatches("/") .'>';
        $navBar .= '<a href="/">Home</a></li>';
        foreach ($navItems as $name => $url) {
            $navBar .= PHP_EOL;
            $navBar .= "<li" . $this->getActiveClassIfRequestMatches($url) .">";
            $navBar .= "<a href='{$url}'>{$name}</a></li>";
        }
        $selectboxHtml = "<!-- select box would appear here -->";
        if (!is_null($selectbox)) {
            $selectboxHtml = "<div class='nav navbar-nav navbar-right'>";
            $selectboxHtml .= $selectbox . "</div>";
        } elseif (!is_null($this->selectBox)) {
            $selectboxHtml = "<div class='nav navbar-nav navbar-right'>";
            $selectboxHtml .= $this->selectBox . "</div>";
        }

        $timeselect = $this->getTimeSelectBox($times);

        $header = <<<"EOD"
<!DOCTYPE html>
<html lang="en">
  <head>
    <meta charset="utf-8">
    <meta http-equiv="X-UA-Compatible" content="IE=edge">
    <meta name="viewport" content="width=device-width, initial-scale=1">
    <title>Dashboards</title>

    <!-- Latest compiled and minified CSS -->
    <link rel="stylesheet" href="//netdna.bootstrapcdn.com/bootstrap/3.1.1/css/bootstrap.min.css">

    <!-- Optional theme -->
    <link rel="stylesheet" href="//netdna.bootstrapcdn.com/bootstrap/3.1.1/css/bootstrap-theme.min.css">

    <style>
        body {
            padding-top: 65px;
        }
    </style>

    <!--[if lt IE 9]>
      <script src="https://oss.maxcdn.com/libs/html5shiv/3.7.0/html5shiv.js"></script>
      <script src="https://oss.maxcdn.com/libs/respond.js/1.4.2/respond.min.js"></script>
    <![endif]-->
  </head>
  <body>
    <div class="navbar navbar-default navbar-fixed-top" role="navigation">
      <div class="container">
        <div class="navbar-header">
          <button type="button" class="navbar-toggle" data-toggle="collapse" data-target=".navbar-collapse">
            <span class="sr-only">Toggle navigation</span>
            <span class="icon-bar"></span>
            <span class="icon-bar"></span>
            <span class="icon-bar"></span>
          </button>
          <a class="navbar-brand" href="#">{$title} </a>
        </div>
        <div class="collapse navbar-collapse">
          <ul class="nav navbar-nav">
            {$navBar}
          </ul>
            <div class='nav navbar-nav navbar-left'>
            {$timeselect}
            </div>
            {$selectboxHtml}
        </div><!--/.nav-collapse -->
      </div>
    </div>
  <div class="container">
EOD;
        return $header;
    }

    /**
     * get footer for page. This should always be called if getHeader() has
     * been called before as they complement each other.
     *
     * Returns the footer as a string
     */
    public function getFooter()
    {
        $footer = <<<"EOF"
    </div>
    <!-- jQuery (necessary for Bootstrap's JavaScript plugins) -->
    <script src="https://ajax.googleapis.com/ajax/libs/jquery/1.11.0/jquery.min.js"></script>
    <!-- Include all compiled plugins (below), or include individual files as needed -->
    <!-- Latest compiled and minified JavaScript -->
    <script src="//netdna.bootstrapcdn.com/bootstrap/3.1.1/js/bootstrap.min.js"></script>
  </body>
</html>
EOF;
        return $footer;
    }
}