pihole.php 5.0 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185
  1. <?php
  2. trait PiHoleHomepageItem
  3. {
  4. public function piholeSettingsArray()
  5. {
  6. return array(
  7. 'name' => 'Pi-hole',
  8. 'enabled' => true,
  9. 'image' => 'plugins/images/tabs/pihole.png',
  10. 'category' => 'Monitor',
  11. 'settings' => array(
  12. 'Enable' => array(
  13. array(
  14. 'type' => 'switch',
  15. 'name' => 'homepagePiholeEnabled',
  16. 'label' => 'Enable',
  17. 'value' => $this->config['homepagePiholeEnabled']
  18. ),
  19. array(
  20. 'type' => 'select',
  21. 'name' => 'homepagePiholeAuth',
  22. 'label' => 'Minimum Authentication',
  23. 'value' => $this->config['homepagePiholeAuth'],
  24. 'options' => $this->groupOptions
  25. )
  26. ),
  27. 'Connection' => array(
  28. array(
  29. 'type' => 'input',
  30. 'name' => 'piholeURL',
  31. 'label' => 'URL',
  32. 'value' => $this->config['piholeURL'],
  33. 'help' => 'Please make sure to use local IP address and port and to include \'/admin/\' at the end of the URL. You can add multiple Pi-holes by comma separating the URLs.',
  34. 'placeholder' => 'http(s)://hostname:port/admin/'
  35. ),
  36. ),
  37. 'Misc' => array(
  38. array(
  39. 'type' => 'switch',
  40. 'name' => 'piholeHeaderToggle',
  41. 'label' => 'Toggle Title',
  42. 'value' => $this->config['piholeHeaderToggle'],
  43. 'help' => 'Shows/hides the title of this homepage module'
  44. ),
  45. array(
  46. 'type' => 'switch',
  47. 'name' => 'homepagePiholeCombine',
  48. 'label' => 'Combine stat cards',
  49. 'value' => $this->config['homepagePiholeCombine'],
  50. 'help' => 'This controls whether to combine the stats for multiple pihole instances into 1 card.',
  51. ),
  52. ),
  53. 'Test Connection' => array(
  54. array(
  55. 'type' => 'blank',
  56. 'label' => 'Please Save before Testing'
  57. ),
  58. array(
  59. 'type' => 'button',
  60. 'label' => '',
  61. 'icon' => 'fa fa-flask',
  62. 'class' => 'pull-right',
  63. 'text' => 'Test Connection',
  64. 'attr' => 'onclick="testAPIConnection(\'pihole\')"'
  65. ),
  66. )
  67. )
  68. );
  69. }
  70. public function testConnectionPihole()
  71. {
  72. if (empty($this->config['piholeURL'])) {
  73. $this->setAPIResponse('error', 'Pihole URL is not defined', 422);
  74. return false;
  75. }
  76. $api = array();
  77. $failed = false;
  78. $errors = '';
  79. $urls = explode(',', $this->config['piholeURL']);
  80. foreach ($urls as $url) {
  81. $url = $url . '/api.php?';
  82. try {
  83. $response = Requests::get($url, [], []);
  84. if ($response->success) {
  85. @$test = json_decode($response->body, true);
  86. if (!is_array($test)) {
  87. $ip = $this->qualifyURL($url, true)['host'];
  88. $errors .= $ip . ': Response was not JSON';
  89. $failed = true;
  90. }
  91. }
  92. if (!$response->success) {
  93. $ip = $this->qualifyURL($url, true)['host'];
  94. $errors .= $ip . ': Unknown Failure';
  95. $failed = true;
  96. }
  97. } catch (Requests_Exception $e) {
  98. $failed = true;
  99. $ip = $this->qualifyURL($url, true)['host'];
  100. $errors .= $ip . ': ' . $e->getMessage();
  101. $this->writeLog('error', 'Pi-hole Connect Function - Error: ' . $e->getMessage(), 'SYSTEM');
  102. };
  103. }
  104. if ($failed) {
  105. $this->setAPIResponse('error', $errors, 500);
  106. return false;
  107. } else {
  108. $this->setAPIResponse('success', null, 200);
  109. return true;
  110. }
  111. }
  112. public function piholeHomepagePermissions($key = null)
  113. {
  114. $permissions = [
  115. 'main' => [
  116. 'enabled' => [
  117. 'homepagePiholeEnabled'
  118. ],
  119. 'auth' => [
  120. 'homepagePiholeAuth'
  121. ],
  122. 'not_empty' => [
  123. 'piholeURL'
  124. ]
  125. ]
  126. ];
  127. if (array_key_exists($key, $permissions)) {
  128. return $permissions[$key];
  129. } elseif ($key == 'all') {
  130. return $permissions;
  131. } else {
  132. return [];
  133. }
  134. }
  135. public function homepageOrderPihole()
  136. {
  137. if ($this->homepageItemPermissions($this->piholeHomepagePermissions('main'))) {
  138. return '
  139. <div id="' . __FUNCTION__ . '">
  140. <div class="white-box homepage-loading-box"><h2 class="text-center" lang="en">Loading Pihole...</h2></div>
  141. <script>
  142. // Pi-hole Stats
  143. homepagePihole("' . $this->config['homepagePiholeRefresh'] . '");
  144. // End Pi-hole Stats
  145. </script>
  146. </div>
  147. ';
  148. }
  149. }
  150. public function getPiholeHomepageStats()
  151. {
  152. if (!$this->homepageItemPermissions($this->piholeHomepagePermissions('main'), true)) {
  153. return false;
  154. }
  155. $api = array();
  156. $urls = explode(',', $this->config['piholeURL']);
  157. foreach ($urls as $url) {
  158. $url = $url . '/api.php?';
  159. try {
  160. $response = Requests::get($url, [], []);
  161. if ($response->success) {
  162. @$piholeResults = json_decode($response->body, true);
  163. if (is_array($piholeResults)) {
  164. $ip = $this->qualifyURL($url, true)['host'];
  165. $api['data'][$ip] = $piholeResults;
  166. }
  167. }
  168. } catch (Requests_Exception $e) {
  169. $this->setAPIResponse('error', $e->getMessage(), 500);
  170. $this->writeLog('error', 'Pi-hole Connect Function - Error: ' . $e->getMessage(), 'SYSTEM');
  171. return false;
  172. };
  173. }
  174. $api['options']['combine'] = $this->config['homepagePiholeCombine'];
  175. $api['options']['title'] = $this->config['piholeHeaderToggle'];
  176. $api = isset($api) ? $api : null;
  177. $this->setAPIResponse('success', null, 200, $api);
  178. return $api;
  179. }
  180. }