"Fossies" - the Fresh Open Source Software Archive 
Member "fogproject-1.5.9/packages/web/lib/fog/fogpage.class.php" (13 Sep 2020, 140509 Bytes) of package /linux/misc/fogproject-1.5.9.tar.gz:
The requested HTML page contains a <FORM> tag that is unusable on "Fossies" in "automatic" (rendered) mode so that page is shown as HTML source code syntax highlighting (style:
standard) with prefixed line numbers and
code folding option.
Alternatively you can here
view or
download the uninterpreted source code file. See also the latest
Fossies "Diffs" side-by-side code changes report for "fogpage.class.php":
1.5.8_vs_1.5.9.
1 <?php
2 /**
3 * Presents many defaults for the pages and is
4 * the calling point by all other page items.
5 *
6 * PHP version 5
7 *
8 * @category FOGPage
9 * @package FOGProject
10 * @author Tom Elliott <tommygunsster@gmail.com>
11 * @license http://opensource.org/licenses/gpl-3.0 GPLv3
12 * @link https://fogproject.org
13 */
14 /**
15 * Presents many defaults for the pages and is
16 * the calling point by all other page items.
17 *
18 * @category FOGPage
19 * @package FOGProject
20 * @author Tom Elliott <tommygunsster@gmail.com>
21 * @license http://opensource.org/licenses/gpl-3.0 GPLv3
22 * @link https://fogproject.org
23 */
24 abstract class FOGPage extends FOGBase
25 {
26 /**
27 * Name of the page
28 *
29 * @var string
30 */
31 public $name = '';
32 /**
33 * Node of the page
34 *
35 * @var string
36 */
37 public $node = '';
38 /**
39 * ID of the page
40 *
41 * @var string
42 */
43 public $id = 'id';
44 /**
45 * Title for segment
46 *
47 * @var string
48 */
49 public $title;
50 /**
51 * The menu (always display)
52 *
53 * @var array
54 */
55 public $menu = array();
56 /**
57 * The submenu (Object displayed menus)
58 *
59 * @var array
60 */
61 public $subMenu = array();
62 /**
63 * Additional notes for object
64 *
65 * @var array
66 */
67 public $notes = array();
68 /**
69 * Table header data
70 *
71 * @var array
72 */
73 public $headerData = array();
74 /**
75 * Table data
76 *
77 * @var array
78 */
79 public $data = array();
80 /**
81 * Template data to replace
82 *
83 * @var array
84 */
85 public $templates = array();
86 /**
87 * Attributes such as class, id, etc...
88 *
89 * @var array
90 */
91 public $attributes = array();
92 /**
93 * Pages that contain objects
94 *
95 * @var array
96 */
97 protected $PagesWithObjects = array(
98 'user',
99 'host',
100 'image',
101 'group',
102 'snapin',
103 'printer',
104 'storage'
105 );
106 /**
107 * The items table
108 *
109 * @var string
110 */
111 protected $databaseTable = '';
112 /**
113 * The items table field and common names
114 *
115 * @var array
116 */
117 protected $databaseFields = array();
118 /**
119 * The items required fields
120 *
121 * @var array
122 */
123 protected $databaseFieldsRequired = array();
124 /**
125 * Database -> Class field relationships
126 *
127 * @var array
128 */
129 protected $databaseFieldClassRelationships = array();
130 /**
131 * The items additional fields
132 *
133 * @var array
134 */
135 protected $additionalFields = array();
136 /**
137 * The forms action placeholder
138 *
139 * @var string
140 */
141 public $formAction = '';
142 /**
143 * The forms method/action
144 *
145 * @var string
146 */
147 protected $formPostAction = '';
148 /**
149 * The items caller class
150 *
151 * @var string
152 */
153 protected $childClass = '';
154 /**
155 * The report place holder
156 *
157 * @var string
158 */
159 protected $reportString = '';
160 /**
161 * Is the title enabled
162 *
163 * @var bool
164 */
165 protected $titleEnabled = true;
166 /**
167 * Fields to data
168 *
169 * @var mixed
170 */
171 protected $fieldsToData;
172 /**
173 * The request
174 *
175 * @var array
176 */
177 protected $request = array();
178 /**
179 * PDF Place holder
180 *
181 * @var string
182 */
183 protected static $pdffile = '';
184 /**
185 * CSV Place holder
186 *
187 * @var string
188 */
189 protected static $csvfile = '';
190 /**
191 * Inventory csv head
192 *
193 * @var string
194 */
195 protected static $inventoryCsvHead = '';
196 /**
197 * Holder for lambda function
198 *
199 * @var function
200 */
201 protected static $returnData;
202 /**
203 * Initializes the page class
204 *
205 * @param mixed $name name of the page to initialize
206 *
207 * @return void
208 */
209 public function __construct($name = '')
210 {
211 parent::__construct();
212 if (self::$ajax) {
213 session_write_close();
214 ignore_user_abort(true);
215 set_time_limit(0);
216 }
217 self::$HookManager->processEvent(
218 'PAGES_WITH_OBJECTS',
219 array('PagesWithObjects' => &$this->PagesWithObjects)
220 );
221 global $node;
222 global $type;
223 global $sub;
224 global $tab;
225 global $id;
226 if ($node == 'report') {
227 $f = filter_input(INPUT_GET, 'f');
228 }
229 if ($node !== 'service'
230 && false !== stripos($sub, 'edit')
231 && (!isset($id)
232 || !is_numeric($id)
233 || $id < 1)
234 ) {
235 self::setMessage(
236 _('ID Must be set to edit')
237 );
238 self::redirect(
239 "?node=$node"
240 );
241 exit;
242 }
243 $subs = array(
244 'configure',
245 'authorize',
246 'requestClientInfo'
247 );
248 if (in_array($sub, $subs)) {
249 return $this->{$sub}();
250 }
251 $this->childClass = ucfirst($this->node);
252 if ($node == 'storage') {
253 $ref = stripos(
254 self::$httpreferer,
255 'node=storage&sub=storageGroup'
256 );
257 }
258 if (!isset($ref) || false === $ref) {
259 $ref = stripos(
260 $sub,
261 'storageGroup'
262 );
263 }
264 if ($ref) {
265 $this->childClass .= 'Group';
266 } elseif ($node == 'storage') {
267 $this->childClass = 'StorageNode';
268 }
269 if (strtolower($this->childClass) === 'storagenodegroup') {
270 $this->childClass = 'StorageGroup';
271 }
272 if (!empty($name)) {
273 $this->name = $name;
274 }
275 $this->title = $this->name;
276 if (in_array($this->node, $this->PagesWithObjects)) {
277 $classVars = self::getClass(
278 $this->childClass,
279 '',
280 true
281 );
282 $this->databaseTable
283 = $classVars['databaseTable'];
284 $this->databaseFields
285 = $classVars['databaseFields'];
286 $this->databaseFieldsRequired
287 = $classVars['databaseFieldsRequired'];
288 $this->databaseFieldClassRelationships
289 = $classVars['databaseFieldClassRelationships'];
290 $this->additionalFields
291 = $classVars['additionalFields'];
292 unset($classVars);
293 $this->obj = self::getClass(
294 $this->childClass,
295 $id
296 );
297 if (isset($id)) {
298 $link = sprintf(
299 '?node=%s&sub=%s&%s=%d',
300 $this->node,
301 '%s',
302 $this->id,
303 $id
304 );
305 $this->delformat = sprintf(
306 $link,
307 'delete'
308 );
309 $this->linkformat = sprintf(
310 $link,
311 'edit'
312 );
313 $this->membership = sprintf(
314 $link,
315 'membership'
316 );
317 if ($id === 0 || !is_numeric($id) || !$this->obj->isValid()) {
318 unset($this->obj);
319 self::setMessage(
320 sprintf(
321 _('%s ID %d is not valid'),
322 $this->childClass,
323 $id
324 )
325 );
326 self::redirect(
327 sprintf(
328 '?node=%s',
329 $this->node
330 )
331 );
332 }
333 $this->name .= ' '
334 . _('Edit')
335 . ': '
336 . $this->obj->get('name');
337 }
338 }
339 $this->reportString = '<h4 class="title">'
340 . '<div id="exportDiv"></div>'
341 . '<a id="csvsub" href="../management/export.php?filename=%s&type=csv" '
342 . 'alt="%s" title="%s" target="_blank" data-toggle="tooltip" '
343 . 'data-placement="top">%s</a> '
344 . '<a id="pdfsub" href="../management/export.php?filename=%s&type=pdf" '
345 . 'alt="%s" title="%s" target="_blank" data-toggle="tooltip" '
346 . 'data-placement="top">%s</a>'
347 . '</h4>';
348 self::$pdffile = '<i class="fa fa-file-pdf-o fa-2x"></i>';
349 self::$csvfile = '<i class="fa fa-file-excel-o fa-2x"></i>';
350 self::$inventoryCsvHead = array(
351 _('Host ID') => 'id',
352 _('Host name') => 'name',
353 _('Host MAC') => 'mac',
354 _('Host Desc') => 'description',
355 _('Inventory ID') => 'id',
356 _('Inventory Desc') => 'description',
357 _('Primary User') => 'primaryUser',
358 _('Other Tag 1') => 'other1',
359 _('Other Tag 2') => 'other2',
360 _('System Manufacturer') => 'sysman',
361 _('System Product') => 'sysproduct',
362 _('System Version') => 'sysversion',
363 _('System Serial') => 'sysserial',
364 _('System Type') => 'systype',
365 _('BIOS Version') => 'biosversion',
366 _('BIOS Vendor') => 'biosvendor',
367 _('BIOS Date') => 'biosdate',
368 _('MB Manufacturer') => 'mbman',
369 _('MB Name') => 'mbproductname',
370 _('MB Version') => 'mbversion',
371 _('MB Serial') => 'mbserial',
372 _('MB Asset') => 'mbasset',
373 _('CPU Manufacturer') => 'cpuman',
374 _('CPU Version') => 'cpuversion',
375 _('CPU Speed') => 'cpucurrent',
376 _('CPU Max Speed') => 'cpumax',
377 _('Memory') => 'mem',
378 _('HD Model') => 'hdmodel',
379 _('HD Firmware') => 'hdfirmware',
380 _('HD Serial') => 'hdserial',
381 _('Chassis Manufacturer') => 'caseman',
382 _('Chassis Version') => 'casever',
383 _('Chassis Serial') => 'caseser',
384 _('Chassis Asset') => 'caseasset',
385 );
386 $this->menu = array(
387 'list' => sprintf(
388 self::$foglang['ListAll'],
389 _(
390 sprintf(
391 '%ss',
392 $this->childClass
393 )
394 )
395 ),
396 'add' => sprintf(
397 self::$foglang['CreateNew'],
398 _($this->childClass)
399 ),
400 'export' => sprintf(
401 self::$foglang[
402 sprintf(
403 'Export%s',
404 $this->childClass
405 )
406 ]
407 ),
408 'import' => sprintf(
409 self::$foglang[
410 sprintf(
411 'Import%s',
412 $this->childClass
413 )
414 ]
415 ),
416 );
417 $this->fieldsToData = function (&$input, &$field) {
418 $this->data[] = array(
419 'field' => $field,
420 'input' => $input,
421 );
422 if (is_array($this->span) && count($this->span) === 2) {
423 $this->data[count($this->data)-1][$this->span[0]] = $this->span[1];
424 }
425 unset($input);
426 };
427 $nodestr = $substr = $idstr = $typestr = $tabstr = false;
428 $formstr = '?';
429 if ($node) {
430 $data['node'] = $node;
431 }
432 if ($sub) {
433 $data['sub'] = $sub;
434 }
435 if ($id) {
436 $data['id'] = $id;
437 }
438 if ($type) {
439 $data['type'] = $type;
440 }
441 if ($f) {
442 $data['f'] = $f;
443 }
444 if ($tab) {
445 $tabstr = "#$tab";
446 }
447 if (is_array($data) && count($data) > 0) {
448 $formstr .= http_build_query($data);
449 }
450 if ($tabstr) {
451 $formstr .= $tabstr;
452 }
453 $this->formAction = $formstr;
454 self::$HookManager->processEvent(
455 'SEARCH_PAGES',
456 array('searchPages' => &self::$searchPages)
457 );
458 self::$HookManager->processEvent(
459 'SUB_MENULINK_DATA',
460 array(
461 'menu' => &$this->menu,
462 'submenu' => &$this->subMenu,
463 'id' => &$this->id,
464 'notes' => &$this->notes
465 )
466 );
467 }
468 /**
469 * Page default index
470 *
471 * @return void
472 */
473 public function index()
474 {
475 if (false === self::$showhtml) {
476 return;
477 }
478 $this->title = _('Search');
479 if (in_array($this->node, self::$searchPages)) {
480 $this->title = sprintf(
481 '%s %s',
482 _('All'),
483 _("{$this->childClass}s")
484 );
485 global $node;
486 global $sub;
487 $manager = sprintf(
488 '%sManager',
489 $this->childClass
490 );
491 $this->data = array();
492 $find = '';
493 if ('Host' === $this->childClass) {
494 $find = array(
495 'pending' => array(0, '')
496 );
497 }
498 Route::listem($this->childClass);
499 $items = json_decode(Route::getData());
500 $type = $node.'s';
501 $items = $items->$type;
502 if (is_array($items) && count($items) > 0) {
503 array_walk($items, static::$returnData);
504 }
505 $event = sprintf(
506 '%s_DATA',
507 strtoupper($this->node)
508 );
509 self::$HookManager->processEvent(
510 $event,
511 array(
512 'data' => &$this->data,
513 'templates' => &$this->templates,
514 'attributes' => &$this->attributes,
515 'headerData' => &$this->headerData
516 )
517 );
518 $event = sprintf(
519 '%s_HEADER_DATA',
520 strtoupper($this->node)
521 );
522 self::$HookManager->processEvent(
523 $event,
524 array(
525 'headerData' => &$this->headerData
526 )
527 );
528 echo '<div class="col-xs-9">';
529 $this->indexDivDisplay();
530 echo '</div>';
531 unset(
532 $this->headerData,
533 $this->data,
534 $this->templates,
535 $this->attributes
536 );
537 } else {
538 $vals = function (&$value, $key) {
539 return sprintf(
540 '%s : %s',
541 $key,
542 $value
543 );
544 };
545 if (is_array($args) && count($args) > 0) {
546 array_walk($args, $vals);
547 }
548 printf(
549 'Index page of: %s%s',
550 get_class($this),
551 (
552 (is_array($args) && count($args)) ?
553 sprintf(
554 ', Arguments = %s',
555 implode(
556 ', ',
557 $args
558 )
559 ) :
560 ''
561 )
562 );
563 }
564 }
565 /**
566 * Set's value to key
567 *
568 * @param string $key the key to set
569 * @param mixed $value the value to set
570 *
571 * @return object
572 */
573 public function set($key, $value)
574 {
575 $this->$key = $value;
576 return $this;
577 }
578 /**
579 * Gets the value in the key
580 *
581 * @param string $key the key to get
582 *
583 * @return mixed
584 */
585 public function get($key)
586 {
587 return $this->$key;
588 }
589 /**
590 * Return the information
591 *
592 * @return string
593 */
594 public function __toString()
595 {
596 return $this->process();
597 }
598 /**
599 * Print the information
600 *
601 * @param int $colsize Col size
602 *
603 * @return void
604 */
605 public function render($colsize = 9)
606 {
607 echo $this->process($colsize);
608 }
609 /**
610 * Process the information
611 *
612 * @param int $colsize Col Size
613 *
614 * @return string
615 */
616 public function process($colsize = 9)
617 {
618 try {
619 unset($actionbox);
620 global $sub;
621 global $node;
622 $defaultScreen = strtolower(self::$defaultscreen);
623 $defaultScreens = array(
624 'search',
625 'list'
626 );
627 $actionbox = '';
628 if (((!$sub
629 || in_array($sub, $defaultScreens)
630 || $sub === 'storageGroup')
631 && in_array($node, self::$searchPages)
632 && in_array($node, $this->PagesWithObjects))
633 ) {
634 if ($node == 'host') {
635 $actionbox .= '</div>';
636 $actionbox .= '</div>';
637 $actionbox .= '<div class='
638 . '"action-boxes host '
639 . 'hiddeninitially">';
640 $actionbox .= '<div class="panel panel-info">';
641 $actionbox .= '<div class="panel-heading text-center">';
642 $actionbox .= '<h4 class="title">';
643 $actionbox .= _('Group Associations');
644 $actionbox .= '</h4>';
645 $actionbox .= '</div>';
646 $actionbox .= '<div class="panel-body">';
647 $actionbox .= '<form class='
648 . '"form-horizontal" '
649 . 'method="post" '
650 . 'action="'
651 . '?node='
652 . $node
653 . '&sub=saveGroup">';
654 $actionbox .= '<div class="form-group">';
655 $actionbox .= '<label class="control-label col-xs-4" for=';
656 $actionbox .= '"group_new">';
657 $actionbox .= _('Create new group');
658 $actionbox .= '</label>';
659 $actionbox .= '<div class="col-xs-8">';
660 $actionbox .= '<div class="input-group">';
661 $actionbox .= '<input type="hidden" name="hostIDArray"/>';
662 $actionbox .= '<input type="text" name="group_new" id='
663 . '"group_new" class="form-control"/>';
664 $actionbox .= '</div>';
665 $actionbox .= '</div>';
666 $actionbox .= '</div>';
667 $actionbox .= '<div class="form-group">';
668 $actionbox .= '<div class="text-center">';
669 $actionbox .= '<label class="control-label">';
670 $actionbox .= _('or');
671 $actionbox .= '</label>';
672 $actionbox .= '</div>';
673 $actionbox .= '</div>';
674 $actionbox .= '<div class="form-group">';
675 $actionbox .= '<label class="control-label col-xs-4" for=';
676 $actionbox .= '"group">';
677 $actionbox .= _('Add to group');
678 $actionbox .= '</label>';
679 $actionbox .= '<div class="col-xs-8">';
680 $actionbox .= self::getClass('GroupManager')->buildSelectBox();
681 $actionbox .= '</div>';
682 $actionbox .= '</div>';
683 $actionbox .= '<div class="form-group">';
684 $actionbox .= '<label class="control-label col-xs-4" for=';
685 $actionbox .= '"process">';
686 $actionbox .= _('Make changes?');
687 $actionbox .= '</label>';
688 $actionbox .= '<div class="col-xs-8">';
689 $actionbox .= '<button type="submit" class='
690 . '"btn btn-info btn-block" name="process" id="process">';
691 $actionbox .= _('Update');
692 $actionbox .= '</button>';
693 $actionbox .= '</div>';
694 $actionbox .= '</div>';
695 $actionbox .= '</form>';
696 $actionbox .= '</div>';
697 $actionbox .= '</div>';
698 $actionbox .= '</div>';
699 }
700 if ($node != 'task') {
701 if (!$actionbox) {
702 $actionbox .= '</div>';
703 $actionbox .= '</div>';
704 }
705 $actionbox .= '<div class='
706 . '"action-boxes del hiddeninitially">';
707 $actionbox .= '<div class="panel panel-warning">';
708 $actionbox .= '<div class="panel-heading text-center">';
709 $actionbox .= '<h4 class="title">';
710 $actionbox .= _('Delete Selected');
711 $actionbox .= '</h4>';
712 $actionbox .= '</div>';
713 $actionbox .= '<div class="panel-body">';
714 $actionbox .= '<form class='
715 . '"form-horizontal" '
716 . 'method="post" '
717 . 'action="'
718 . '?node='
719 . $node
720 . '&sub=deletemulti">';
721 $actionbox .= '<div class="form-group">';
722 $actionbox .= '<label class="control-label col-xs-4" for='
723 . '"del-'
724 . $node
725 . '">';
726 $actionbox .= sprintf(
727 '%s %ss',
728 _('Delete selected'),
729 (
730 strtolower($node) !== 'storage' ?
731 strtolower($node) :
732 (
733 $sub === 'storageGroup' ?
734 strtolower($node) . ' group' :
735 strtolower($node) . ' node'
736 )
737 )
738 );
739 $actionbox .= '</label>';
740 $actionbox .= '<div class="col-xs-8">';
741 $actionbox .= '<input type="hidden" name="'
742 . strtolower($node)
743 . 'IDArray"/>';
744 $actionbox .= '<button type="submit" class='
745 . '"btn btn-danger btn-block" id="'
746 . 'del-'
747 . $node
748 . '">';
749 $actionbox .= _('Delete');
750 $actionbox .= '</button>';
751 $actionbox .= '</div>';
752 $actionbox .= '</div>';
753 $actionbox .= '</form>';
754 $actionbox .= '</div>';
755 $actionbox .= '</div>';
756 $actionbox .= '</div>';
757 }
758 }
759 self::$HookManager->processEvent(
760 'ACTIONBOX',
761 array('actionbox' => &$actionbox)
762 );
763 if (self::$ajax) {
764 echo json_encode(
765 array(
766 'data' => $this->data,
767 'templates' => $this->templates,
768 'headerData' => $this->headerData,
769 'title' => $this->title,
770 'attributes' => $this->attributes,
771 'form' => $this->form,
772 'actionbox' => (
773 (is_array($this->data) && count($this->data) > 0) ?
774 $actionbox :
775 ''
776 ),
777 )
778 );
779 exit;
780 }
781 if (!count($this->templates)) {
782 throw new Exception(
783 _('Requires templates to process')
784 );
785 }
786 if (in_array($node, array('task'))
787 && (!$sub || $sub == 'list')
788 ) {
789 self::redirect(
790 sprintf(
791 '?node=%s&sub=active',
792 $node
793 )
794 );
795 }
796 ob_start();
797 if (isset($this->form)) {
798 printf($this->form);
799 }
800 if ($node != 'home') {
801 echo '<div class="table-holder col-xs-'
802 . $colsize
803 . '">';
804 }
805 echo '<table class="table table-responsive'
806 . (
807 is_array($this->data) && count($this->data) < 1 ?
808 ' noresults' :
809 ''
810 )
811 . '">';
812 if (is_array($this->data) && count($this->data) < 1) {
813 echo '<thead><tr class="header"></tr></thead>';
814 echo '<tbody>';
815 $tablestr = '<tr><td colspan="'
816 . count($this->templates)
817 . '">';
818 if ($this->data['error']) {
819 $tablestr .= (
820 is_array($this->data['error']) ?
821 '<p>'
822 . implode('</p><p>', $this->data['error'])
823 : $this->data['error']
824 );
825 } else {
826 $tablestr .= self::$foglang['NoResults'];
827 }
828 $tablestr .= '</td></tr>';
829 echo $tablestr;
830 echo '</tbody>';
831 } else {
832 if (is_array($this->headerData) && count($this->headerData) > 0) {
833 echo '<thead>';
834 echo $this->buildHeaderRow();
835 echo '</thead>';
836 }
837 echo '<tbody>';
838 $tablestr = '';
839 foreach ((array)$this->data as &$rowData) {
840 $tablestr .= '<tr class="'
841 . strtolower($node)
842 . '" '
843 . (
844 isset($rowData['id']) || isset($rowData[$id_field]) ?
845 'id="'
846 . $node
847 . '-'
848 . (
849 isset($rowData['id']) ?
850 $rowData['id'] . '"' :
851 $rowData[$id_field] . '"'
852 ) :
853 ''
854 )
855 . '>';
856 $tablestr .= $this->buildRow($rowData);
857 $tablestr .= '</tr>';
858 unset($rowData);
859 }
860 echo $tablestr;
861 echo '</tbody>';
862 }
863 echo '</table>';
864 if ($node != 'home') {
865 echo '</div>';
866 }
867 } catch (Exception $e) {
868 return $e->getMessage();
869 }
870 return ob_get_clean()
871 . $actionbox;
872 }
873 /**
874 * Sets the attributes
875 *
876 * @return void
877 */
878 private function _setAtts()
879 {
880 foreach ((array)$this->attributes as $index => &$attribute) {
881 foreach ((array)$attribute as $name => &$val) {
882 $this->atts[$index] .= sprintf(
883 ' %s="%s" ',
884 $name,
885 (
886 $this->dataFind ?
887 str_replace($this->dataFind, $this->dataReplace, $val) :
888 $val
889 )
890 );
891 unset($name);
892 }
893 unset($attribute);
894 }
895 }
896 /**
897 * Builds the header row
898 *
899 * @return string
900 */
901 public function buildHeaderRow()
902 {
903 unset($this->atts);
904 $this->_setAtts();
905 if (is_array($this->headerData) && count($this->headerData) < 1) {
906 return;
907 }
908 ob_start();
909 echo '<tr class="header'
910 . (
911 is_array($this->data) && count($this->data) < 1 ?
912 ' hiddeninitially' :
913 ''
914 )
915 . '">';
916 foreach ($this->headerData as $index => &$content) {
917 echo '<th'
918 . (
919 $this->atts[$index] ?
920 ' '
921 . $this->atts[$index]
922 . ' ' :
923 ' '
924 )
925 . 'data-column="'
926 . $index
927 . '">';
928 echo $content;
929 echo '</th>';
930 unset($content);
931 }
932 echo '</tr>';
933 return ob_get_clean();
934 }
935 /**
936 * Replaces the data for templated information
937 *
938 * @param mixed $data the data to replace
939 *
940 * @return string
941 */
942 private function _replaceNeeds($data)
943 {
944 unset(
945 $this->dataFind,
946 $this->dataReplace
947 );
948 global $node;
949 global $sub;
950 global $tab;
951 $urlvars = array(
952 'node' => $node,
953 'sub' => $sub,
954 'tab' => $tab
955 );
956 $arrayReplace = self::fastmerge(
957 $urlvars,
958 (array)$data
959 );
960 foreach ((array)$arrayReplace as $name => &$val) {
961 $this->dataFind[] = sprintf(
962 '${%s}',
963 $name
964 );
965 $val = trim($val);
966 $this->dataReplace[] = $val;
967 unset($val);
968 }
969 }
970 /**
971 * Builds the row data
972 *
973 * @param mixed $data the data to build off
974 *
975 * @return string
976 */
977 public function buildRow($data)
978 {
979 unset($this->atts);
980 $this->_replaceNeeds($data);
981 $this->_setAtts();
982 ob_start();
983 foreach ((array)$this->templates as $index => &$template) {
984 echo '<td'
985 . (
986 $this->atts[$index] ?
987 ' ' . $this->atts[$index] . ' ' :
988 ''
989 )
990 . '>';
991 echo str_replace(
992 $this->dataFind,
993 $this->dataReplace,
994 $template
995 );
996 echo '</td>';
997 unset($template);
998 }
999 return ob_get_clean();
1000 }
1001 /**
1002 * Presents the tasking items and options
1003 *
1004 * @return void
1005 */
1006 public function deploy()
1007 {
1008 global $type;
1009 global $id;
1010 try {
1011 if (!is_numeric($type) || $type < 1) {
1012 $type = 1;
1013 }
1014 $TaskType = new TaskType($type);
1015 $imagingTypes = $TaskType->isImagingTask();
1016 if ($this->obj instanceof Group) {
1017 if ($this->obj->getHostCount() < 1) {
1018 throw new Exception(
1019 _('Cannot set tasking to invalid hosts')
1020 );
1021 }
1022 }
1023 if ($this->obj instanceof Host) {
1024 if ($this->obj->get('pending')) {
1025 throw new Exception(
1026 _('Cannot set tasking to pending hosts')
1027 );
1028 }
1029 }
1030 if (!$this->obj instanceof Group
1031 && !$this->obj instanceof Host
1032 ) {
1033 throw new Exception(
1034 _('Invalid object to try tasking')
1035 );
1036 }
1037 if ($imagingTypes
1038 && $this->obj instanceof Host
1039 && !$this->obj->getImage()->get('isEnabled')
1040 ) {
1041 throw new Exception(_('Cannot set tasking as image is not enabled'));
1042 }
1043 } catch (Exception $e) {
1044 self::setMessage(
1045 $e->getMessage()
1046 );
1047 self::redirect(
1048 sprintf(
1049 '?node=%s&sub=edit%s',
1050 $this->node,
1051 (
1052 is_numeric($id) && $id > 0 ?
1053 sprintf(
1054 '&%s=%s',
1055 $this->id,
1056 $id
1057 ) :
1058 ''
1059 )
1060 )
1061 );
1062 }
1063 unset($this->headerData);
1064 $this->attributes = array(
1065 array(
1066 'data-toggle' => 'tooltip',
1067 'data-placement' => 'right',
1068 'title' => '${host_title}'
1069 ),
1070 array(),
1071 array(
1072 'data-toggle' => 'tooltip',
1073 'data-placement' => 'right',
1074 'title' => '${image_title}'
1075 )
1076 );
1077 $this->templates = array(
1078 '<a href="${host_link}">${host_name}</a>',
1079 '${host_mac}',
1080 '<a href="${image_link}">${image_name}</a>'
1081 . '<input type="hidden" name="taskhosts[]" value="${host_id}"/>',
1082 );
1083 if ($this->obj instanceof Host) {
1084 ob_start();
1085 echo '<select class="form-control input-group" name="snapin" id="'
1086 . 'snapin" autocomplete="off">';
1087 echo '<option value="">- ';
1088 echo self::$foglang['PleaseSelect'];
1089 echo ' -</option>';
1090 echo '<option disabled>';
1091 echo '---------- '
1092 . _('Host Associated Snapins')
1093 . ' ----------';
1094 echo '</option>';
1095 Route::listem(
1096 'snapin',
1097 'name',
1098 false,
1099 array('id' => $this->obj->get('snapins'))
1100 );
1101 $snapins = json_decode(
1102 Route::getData()
1103 );
1104 $snapins = $snapins->snapins;
1105 foreach ((array)$snapins as &$Snapin) {
1106 echo '<option value="'
1107 . $Snapin->id
1108 . '">';
1109 echo $Snapin->name;
1110 echo ' - (';
1111 echo $Snapin->id;
1112 echo ')';
1113 echo '</option>';
1114 unset($Snapin);
1115 }
1116 unset($snapins);
1117 echo '<option disabled>';
1118 echo '---------- '
1119 . _('Host Unassociated Snapins')
1120 . ' ----------';
1121 echo '</option>';
1122 Route::listem(
1123 'snapin',
1124 'name',
1125 false,
1126 array('id' => $this->obj->get('snapinsnotinme'))
1127 );
1128 $snapins = json_decode(
1129 Route::getData()
1130 );
1131 $snapins = $snapins->snapins;
1132 foreach ((array)$snapins as &$Snapin) {
1133 echo '<option value="'
1134 . $Snapin->id
1135 . '">';
1136 echo $Snapin->name;
1137 echo ' - (';
1138 echo $Snapin->id;
1139 echo ')';
1140 echo '</option>';
1141 unset($Snapin);
1142 }
1143 unset($snapins);
1144 $snapselector = ob_get_clean();
1145 $this->data[] = array(
1146 'host_link' => '?node=host&sub=edit&id=${host_id}',
1147 'image_link' => '?node=image&sub=edit&id=${image_id}',
1148 'host_id' => $this->obj->get('id'),
1149 'image_id' => $this->obj->getImage()->get('id'),
1150 'host_name' => $this->obj->get('name'),
1151 'host_mac' => $this->obj->get('mac'),
1152 'image_name' => $this->obj->getImage()->get('name'),
1153 'host_title' => _('Edit Host'),
1154 'image_title' => _('Edit Image'),
1155 );
1156 } elseif ($this->obj instanceof Group) {
1157 $snapselector = self::getClass('SnapinManager')->buildSelectBox();
1158 Route::listem(
1159 'host',
1160 'name',
1161 false,
1162 ['id' => $this->obj->get('hosts')]
1163 );
1164 $Hosts = json_decode(
1165 Route::getData()
1166 );
1167 $Hosts = $Hosts->hosts;
1168 foreach ((array)$Hosts as &$Host) {
1169 $imageID = $imageName = '';
1170 if ($TaskType->isImagingTask()) {
1171 $Image = $Host->image;
1172 if (!$Image->isEnabled) {
1173 continue;
1174 }
1175 $imageID = $Image->id;
1176 $imageName = $Image->name;
1177 }
1178 $this->data[] = array(
1179 'host_link' => '?node=host&sub=edit&id=${host_id}',
1180 'host_title' => sprintf(
1181 '%s: ${host_name}',
1182 _('Edit')
1183 ),
1184 'host_id' => $Host->id,
1185 'host_name' => $Host->name,
1186 'host_mac' => $Host->primac,
1187 'image_link' => '?node=image&sub=edit&id=${image_id}',
1188 'image_title' => sprintf(
1189 '%s: ${image_name}',
1190 _('Edit')
1191 ),
1192 'image_id' => $imageID,
1193 'image_name' => $imageName,
1194 );
1195 unset(
1196 $index,
1197 $Host,
1198 $Image
1199 );
1200 }
1201 }
1202 self::$HookManager->processEvent(
1203 sprintf(
1204 '%s_DEPLOY',
1205 strtoupper($this->childClass)
1206 ),
1207 array(
1208 'headerData' => &$this->headerData,
1209 'data' => &$this->data,
1210 'templates' => &$this->templates,
1211 'attributes' => &$this->attributes
1212 )
1213 );
1214 echo '<div class="col-xs-9">';
1215 echo '<div class="panel panel-info">';
1216 echo '<div class="panel-heading text-center">';
1217 echo '<h4 class="title">';
1218 echo _('Confirm tasking');
1219 echo '</h4>';
1220 if ($this->obj instanceof Host) {
1221 if ($this->obj->getImage()->isValid()) {
1222 echo '<h5 class="title">';
1223 echo _('Image Associated: ');
1224 echo $this->obj->getImage()->get('name');
1225 echo '</h5>';
1226 }
1227 }
1228 echo '</div>';
1229 echo '<div class="panel-body">';
1230 echo '<form class="form-horizontal" method="post" action="'
1231 . $this->formAction
1232 . '">';
1233 echo '<div class="panel panel-info">';
1234 echo '<div class="panel-heading text-center">';
1235 echo '<h4 class="title">';
1236 echo _('Advanced Settings');
1237 echo '</h4>';
1238 echo '</div>';
1239 echo '<div class="panel-body">';
1240 if ($TaskType->get('id') == 13) {
1241 echo '<div class="form-group">';
1242 echo '<label class="control-label" for="snapin">';
1243 echo _('Please select the snapin you want to install');
1244 echo '</label>';
1245 echo '<div class="input-group">';
1246 echo $snapselector;
1247 echo '</div>';
1248 echo '</div>';
1249 }
1250 if ($TaskType->get('id') == 11) {
1251 echo '<div class="form-group">';
1252 echo '<label class="control-label" for="account">';
1253 echo _('Account name to reset');
1254 echo '</label>';
1255 echo '<div class="input-group">';
1256 echo '<input class="form-control" id="account" type="'
1257 . 'text" name="account" value="Administrator"/>';
1258 echo '</div>';
1259 echo '</div>';
1260 }
1261 if ($TaskType->isInitNeededTasking()
1262 && !$TaskType->isDebug()
1263 ) {
1264 echo '<div class="checkbox hideFromDebug">';
1265 echo '<label for="shutdown">';
1266 echo '<input type="checkbox" name='
1267 . '"shutdown" id="shutdown"'
1268 . (
1269 self::getSetting('FOG_TASKING_ADV_SHUTDOWN_ENABLED') ?
1270 ' checked' :
1271 ''
1272 )
1273 . '/>';
1274 echo _('Schedule with shutdown');
1275 echo '</label>';
1276 echo '</div>';
1277 }
1278 if ($TaskType->get('id') != 14) {
1279 echo '<div class="checkbox">';
1280 echo '<label for="wol">';
1281 echo '<input type="checkbox" name='
1282 . '"wol" id="wol"'
1283 . (
1284 $TaskType->isSnapinTasking() ?
1285 '' :
1286 (
1287 self::getSetting('FOG_TASKING_ADV_WOL_ENABLED') ?
1288 ' checked' :
1289 ''
1290 )
1291 )
1292 . '/>';
1293 echo _('Wake on lan?');
1294 echo '</label>';
1295 echo '</div>';
1296 }
1297 if (!$TaskType->isDebug()
1298 && $TaskType->get('id') != 11
1299 ) {
1300 if ($TaskType->isInitNeededTasking()
1301 && !($this->obj instanceof Group)
1302 ) {
1303 echo '<div class="checkbox">';
1304 echo '<label for="checkDebug">';
1305 echo '<input type="checkbox" name='
1306 . '"isDebugTask" id="checkDebug"'
1307 . (
1308 self::getSetting('FOG_TASKING_ADV_DEBUG_ENABLED') ?
1309 ' checked' :
1310 ''
1311 )
1312 . '/>';
1313 echo _('Schedule as debug task');
1314 echo '</label>';
1315 echo '</div>';
1316 }
1317 }
1318 echo '<div class="radio">';
1319 echo '<label for="scheduleInstant">';
1320 echo '<input type="radio" name='
1321 . '"scheduleType" id="scheduleInstant" value="instant"'
1322 . 'checked/>';
1323 echo _('Schedule instant');
1324 echo '</label>';
1325 echo '</div>';
1326 if (!$TaskType->isDebug()
1327 && $TaskType->get('id') != 11
1328 ) {
1329 // Delayed elements
1330 echo '<div class="hideFromDebug">';
1331 echo '<div class="radio">';
1332 echo '<label for="scheduleSingle">';
1333 echo '<input type="radio" name='
1334 . '"scheduleType" id="scheduleSingle" value="single"/>';
1335 echo _('Schedule delayed');
1336 echo '</label>';
1337 echo '</div>';
1338 echo '<div class="form-group hiddeninitially">';
1339 echo '<label for="scheduleSingleTime">';
1340 echo _('Date and Time');
1341 echo '</label>';
1342 echo '<div class="input-group">';
1343 echo '<input class="form-control" type="text" name='
1344 . '"scheduleSingleTime" id='
1345 . '"scheduleSingleTime">';
1346 echo '</div>';
1347 echo '</div>';
1348 echo '</div>';
1349 // Cron elements
1350 $specialCrons = array(
1351 ''=>_('Select a cron type'),
1352 'yearly'=>sprintf('%s/%s', _('Yearly'), _('Annually')),
1353 'monthly'=>_('Monthly'),
1354 'weekly'=>_('Weekly'),
1355 'daily'=>sprintf('%s/%s', _('Daily'), _('Midnight')),
1356 'hourly'=>_('Hourly'),
1357 );
1358 ob_start();
1359 foreach ($specialCrons as $val => &$name) {
1360 echo '<option value="'
1361 . $val
1362 . '">'
1363 . $name
1364 . '</option>';
1365 unset($name);
1366 }
1367 $cronOpts = ob_get_clean();
1368 echo '<div class="hideFromDebug">';
1369 echo '<div class="radio">';
1370 echo '<label for="scheduleCron">';
1371 echo '<input type="radio" name='
1372 . '"scheduleType" id="scheduleCron" value="cron"/>';
1373 echo _('Schedule cron-style');
1374 echo '</label>';
1375 echo '</div>';
1376 echo '<div class="form-group hiddeninitially">';
1377 echo '<div class="cronOptions input-group">';
1378 echo FOGCron::buildSpecialCron('specialCrons');
1379 echo '</div>';
1380 echo '<div class="col-xs-12">';
1381 echo '<div class="cronInputs">';
1382 echo '<div class="col-xs-2">';
1383 echo '<div class="input-group">';
1384 echo '<input type="text" name="scheduleCronMin" '
1385 . 'placeholder="min" autocomplete="off" '
1386 . 'class="form-control scheduleCronMin cronInput"/>';
1387 echo '</div>';
1388 echo '</div>';
1389 echo '<div class="col-xs-2">';
1390 echo '<div class="input-group">';
1391 echo '<input type="text" name="scheduleCronHour" '
1392 . 'placeholder="hour" autocomplete="off" '
1393 . 'class="form-control scheduleCronHour cronInput"/>';
1394 echo '</div>';
1395 echo '</div>';
1396 echo '<div class="col-xs-2">';
1397 echo '<div class="input-group">';
1398 echo '<input type="text" name="scheduleCronDOM" '
1399 . 'placeholder="dom" autocomplete="off" '
1400 . 'class="form-control scheduleCronDOM cronInput"/>';
1401 echo '</div>';
1402 echo '</div>';
1403 echo '<div class="col-xs-2">';
1404 echo '<div class="input-group">';
1405 echo '<input type="text" name="scheduleCronMonth" '
1406 . 'placeholder="month" autocomplete="off" '
1407 . 'class="form-control scheduleCronMonth cronInput"/>';
1408 echo '</div>';
1409 echo '</div>';
1410 echo '<div class="col-xs-2">';
1411 echo '<div class="input-group">';
1412 echo '<input type="text" name="scheduleCronDOW" '
1413 . 'placeholder="dow" autocomplete="off" '
1414 . 'class="form-control scheduleCronDOW cronInput"/>';
1415 echo '</div>';
1416 echo '</div>';
1417 echo '</div>';
1418 echo '</div>';
1419 echo '</div>';
1420 echo '</div>';
1421 }
1422 if (is_array($this->data) && count($this->data)) {
1423 echo '<div class="col-xs-12">';
1424 echo '<label class="control-label col-xs-4" for="taskingbtn">';
1425 echo _('Create');
1426 echo ' ';
1427 echo $TaskType->get('name');
1428 echo ' ';
1429 echo _('Tasking');
1430 echo '</label>';
1431 echo '<div class="col-xs-8">';
1432 echo '<button type="submit" class="btn btn-info btn-block" id='
1433 . '"taskingbtn">';
1434 echo _('Task');
1435 echo '</button>';
1436 echo '</div>';
1437 echo '</div>';
1438 }
1439 echo '</div>';
1440 echo '</div>';
1441 if ($this->node != 'host') {
1442 echo '<div class="panel panel-info">';
1443 echo '<div class="panel-heading text-center">';
1444 echo '<h4 class="title">';
1445 echo _('Hosts in task');
1446 echo '</h4>';
1447 echo '</div>';
1448 echo '<div class="panel-body text-center">';
1449 $this->render(12);
1450 echo '</div>';
1451 echo '</div>';
1452 }
1453 echo '</form>';
1454 echo '</div>';
1455 echo '</div>';
1456 echo '</div>';
1457 }
1458 /**
1459 * Actually create the tasking
1460 *
1461 * @return void
1462 */
1463 public function deployPost()
1464 {
1465 self::$HookManager->processEvent(
1466 sprintf(
1467 '%s_DEPLOY_POST',
1468 strtoupper($this->childClass)
1469 )
1470 );
1471 global $type;
1472 global $id;
1473 try {
1474 /**
1475 * Task type setup.
1476 */
1477 if (!(is_numeric($type) && $type > 0)) {
1478 $type = 1;
1479 }
1480 $TaskType = new TaskType($type);
1481 /**
1482 * Account Setup.
1483 */
1484 $passreset = filter_input(INPUT_POST, 'account');
1485 /**
1486 * Snapin Setup.
1487 */
1488 $enableSnapins = (int)filter_input(INPUT_POST, 'snapin');
1489 if (0 === $enableSnapins) {
1490 $enableSnapins = -1;
1491 }
1492 if (17 === $type
1493 || $enableSnapins < -1
1494 ) {
1495 $enableSnapins = 0;
1496 }
1497 /**
1498 * Shutdown Setup.
1499 */
1500 $enableShutdown = false;
1501 $shutdown = isset($_POST['shutdown']);
1502 if ($shutdown) {
1503 $enableShutdown = true;
1504 }
1505 /**
1506 * Debug Setup.
1507 */
1508 $enableDebug = false;
1509 $debug = isset($_POST['debug']);
1510 $isdebug = isset($_POST['isDebugTask']);
1511 if ($debug || $isdebug) {
1512 $enableDebug = true;
1513 }
1514 /**
1515 * WOL Setup.
1516 */
1517 $wol = false;
1518 $wolon = isset($_POST['wol']);
1519 if (14 == $type
1520 || $wolon
1521 ) {
1522 $wol = true;
1523 }
1524 $imagingTasks = $TaskType->isImagingTask();
1525 $taskName = sprintf(
1526 '%s Task',
1527 $TaskType->get('name')
1528 );
1529 /**
1530 * Schedule Type Setup.
1531 */
1532 $scheduleType = strtolower(
1533 filter_input(INPUT_POST, 'scheduleType')
1534 );
1535 $scheduleTypes = array(
1536 'cron',
1537 'instant',
1538 'single',
1539 );
1540 self::$HookManager
1541 ->processEvent(
1542 'SCHEDULE_TYPES',
1543 array(
1544 'scheduleTypes' => &$scheduleTypes
1545 )
1546 );
1547 foreach ((array)$scheduleTypes as $ind => &$type) {
1548 $scheduleTypes[$ind] = trim(
1549 strtolower(
1550 $type
1551 )
1552 );
1553 unset($type);
1554 }
1555 if (!in_array($scheduleType, $scheduleTypes)) {
1556 throw new Exception(_('Invalid scheduling type'));
1557 }
1558 /**
1559 * Schedule delayed/cron checks.
1560 */
1561 $scheduleDeployTime = self::niceDate(
1562 filter_input(INPUT_POST, 'scheduleSingleTime')
1563 );
1564 switch ($scheduleType) {
1565 case 'single':
1566 if ($scheduleDeployTime < self::niceDate()) {
1567 throw new Exception(
1568 sprintf(
1569 '%s<br>%s: %s',
1570 _('Scheduled date is in the past'),
1571 _('Date'),
1572 $scheduleDeployTime->format('Y-m-d H:i:s')
1573 )
1574 );
1575 }
1576 break;
1577 case 'cron':
1578 $min = strval(filter_input(INPUT_POST, 'scheduleCronMin'));
1579 $hour = strval(filter_input(INPUT_POST, 'scheduleCronHour'));
1580 $dom = strval(filter_input(INPUT_POST, 'scheduleCronDOM'));
1581 $month = strval(filter_input(INPUT_POST, 'scheduleCronMonth'));
1582 $dow = strval(filter_input(INPUT_POST, 'scheduleCronDOW'));
1583 $valsToSet = array(
1584 'minute' => $min,
1585 'hour' => $hour,
1586 'dayOfMonth' => $dom,
1587 'month' => $month,
1588 'dayOfWeek' => $dow
1589 );
1590 if (!FOGCron::checkMinutesField($min)) {
1591 throw new Exception(
1592 sprintf(
1593 '%s %s invalid',
1594 'checkMinutesField',
1595 _('minute')
1596 )
1597 );
1598 }
1599 if (!FOGCron::checkHoursField($hour)) {
1600 throw new Exception(
1601 sprintf(
1602 '%s %s invalid',
1603 'checkHoursField',
1604 _('hour')
1605 )
1606 );
1607 }
1608 if (!FOGCron::checkDOMField($dom)) {
1609 throw new Exception(
1610 sprintf(
1611 '%s %s invalid',
1612 'checkDOMField',
1613 _('day of month')
1614 )
1615 );
1616 }
1617 if (!FOGCron::checkMonthField($month)) {
1618 throw new Exception(
1619 sprintf(
1620 '%s %s invalid',
1621 'checkMonthField',
1622 _('month')
1623 )
1624 );
1625 }
1626 if (!FOGCron::checkDOWField($dow)) {
1627 throw new Exception(
1628 sprintf(
1629 '%s %s invalid',
1630 'checkDOWField',
1631 _('day of week')
1632 )
1633 );
1634 }
1635 break;
1636 }
1637 // The type is invalid
1638 if (!$TaskType->isValid()) {
1639 throw new Exception(
1640 _('Task type is not valid')
1641 );
1642 }
1643 // Task is password recovery but no account to reset
1644 if ($TaskType->get('id') == 11
1645 && empty($passreset)
1646 ) {
1647 throw new Exception(
1648 _('Password reset requires a user account to reset')
1649 );
1650 }
1651 // Is host pending, don't send
1652 if ($this->obj instanceof Host) {
1653 if ($this->obj->get('pending')) {
1654 throw new Exception(
1655 _('Cannot set tasking to pending hosts')
1656 );
1657 }
1658 } elseif ($this->obj instanceof Group) {
1659 if (!(isset($_POST['taskhosts'])
1660 && count($_POST['taskhosts']) > 0)
1661 ) {
1662 throw new Exception(
1663 _('There are no hosts to task in this group')
1664 );
1665 }
1666 $this->obj->set('hosts', $_POST['taskhosts']);
1667 }
1668 if ($TaskType->isImagingTask()) {
1669 if ($this->obj instanceof Host) {
1670 $Image = $this->obj->getImage();
1671 if (!$Image->isValid()) {
1672 throw new Exception(
1673 _('To perform an imaging task an image must be assigned')
1674 );
1675 }
1676 if (!$Image->get('isEnabled')) {
1677 throw new Exception(
1678 _('Cannot create tasking as image is not enabled')
1679 );
1680 }
1681 if ($TaskType->isCapture()
1682 && $Image->get('protected')
1683 ) {
1684 throw new Exception(
1685 _('The assigned image is protected')
1686 . ' '
1687 . _('and cannot be captured')
1688 );
1689 }
1690 } elseif ($this->obj instanceof Group) {
1691 if ($TaskType->isCapture()) {
1692 throw new Exception(
1693 _('Groups are not allowed to schedule upload tasks')
1694 );
1695 }
1696 if ($TaskType->isMulticast()
1697 && !$this->obj->doMembersHaveUniformImages()
1698 ) {
1699 throw new Exception(
1700 _('Multicast tasks from groups')
1701 . ' '
1702 . _('require all hosts have the same image')
1703 );
1704 }
1705 $imageIDs = self::getSubObjectIDs(
1706 'Host',
1707 array('id' => $this->obj->get('hosts')),
1708 'imageID'
1709 );
1710 $orig_hosts = $this->get('hosts');
1711 $hostIDs = self::getSubObjectIDs(
1712 'Host',
1713 array(
1714 'id' => $this->obj->get('hosts'),
1715 'imageID' => $imageIDs
1716 )
1717 );
1718 if (is_array($hostIDs) && count($hostIDs) < 1) {
1719 throw new Exception(
1720 sprintf(
1721 '%s/%s.',
1722 _('No valid hosts found and'),
1723 _('or no valid images specified')
1724 )
1725 );
1726 }
1727 $this->obj->set('hosts', $hostIDs);
1728 }
1729 }
1730 } catch (Exception $e) {
1731 echo '<div class="col-xs-9">';
1732 echo '<div class="panel panel-danger">';
1733 echo '<div class="panel-heading text-center">';
1734 echo '<h4 class="title">';
1735 echo _('Tasking Failed');
1736 echo '</h4>';
1737 echo '</div>';
1738 echo '<div class="panel-body text-center">';
1739 echo '<div class="row">';
1740 echo _('Failed to create tasking');
1741 echo '</div>';
1742 echo '<div class="row">';
1743 echo $e->getMessage();
1744 echo '</div>';
1745 echo '</div>';
1746 echo '</div>';
1747 echo '</div>';
1748 return;
1749 }
1750 try {
1751 try {
1752 $groupTask = $this->obj instanceof Group;
1753 $success = '';
1754 if ($scheduleType == 'instant') {
1755 $success .= implode(
1756 '</ul><ul>',
1757 (array)$this->obj->createImagePackage(
1758 $TaskType->get('id'),
1759 $taskName,
1760 $enableShutdown,
1761 $enableDebug,
1762 $enableSnapins,
1763 $groupTask,
1764 self::$FOGUser->get('name'),
1765 $passreset,
1766 false,
1767 $wol
1768 )
1769 );
1770 } else {
1771 $ScheduledTask = self::getClass('ScheduledTask')
1772 ->set('taskType', $TaskType->get('id'))
1773 ->set('name', $taskName)
1774 ->set('hostID', $this->obj->get('id'))
1775 ->set('shutdown', $enableShutdown)
1776 ->set('other2', $enableSnapins)
1777 ->set(
1778 'type',
1779 (
1780 $scheduleType == 'single' ?
1781 'S' :
1782 'C'
1783 )
1784 )
1785 ->set('isGroupTask', $groupTask)
1786 ->set('other3', self::$FOGUser->get('name'))
1787 ->set('isActive', 1)
1788 ->set('other4', $wol);
1789 if ($scheduleType == 'single') {
1790 $ScheduledTask->set(
1791 'scheduleTime',
1792 $scheduleDeployTime->getTimestamp()
1793 );
1794 } elseif ($scheduleType == 'cron') {
1795 foreach ((array)$valsToSet as $key => &$val) {
1796 $ScheduledTask->set($key, $val);
1797 unset($val);
1798 }
1799 $ScheduledTask->set('isActive', 1);
1800 }
1801 if (!$ScheduledTask->save()) {
1802 throw new Exception(
1803 _('Failed to create scheduled tasking')
1804 );
1805 }
1806 $success .= _('Scheduled tasks successfully created');
1807 }
1808 } catch (Exception $e) {
1809 $error[] = sprintf(
1810 '%s %s %s<br/>%s',
1811 $this->obj->get('name'),
1812 _('Failed to start tasking type'),
1813 $TaskType->get('name'),
1814 $e->getMessage()
1815 );
1816 }
1817 if (is_array($error) && count($error)) {
1818 throw new Exception(
1819 sprintf(
1820 '<ul class="nav nav-pills nav-stacked">'
1821 . '<li>%s</li>'
1822 . '</ul>',
1823 implode(
1824 '</li><li>',
1825 $error
1826 )
1827 )
1828 );
1829 }
1830 } catch (Exception $e) {
1831 echo '<div class="col-xs-9">';
1832 echo '<div class="panel panel-danger">';
1833 echo '<div class="panel-heading text-center">';
1834 echo '<h4 class="title">';
1835 echo _('Tasking Failed');
1836 echo '</h4>';
1837 echo '</div>';
1838 echo '<div class="panel-body text-center">';
1839 echo '<div class="row">';
1840 echo _('Failed to create tasking');
1841 echo '</div>';
1842 echo '<div class="row">';
1843 echo $e->getMessage();
1844 echo '</div>';
1845 echo '</div>';
1846 echo '</div>';
1847 echo '</div>';
1848 }
1849 if (false == empty($success)) {
1850 switch ($scheduleType) {
1851 case 'cron':
1852 $time = sprintf(
1853 '%s: %s %s %s %s %s',
1854 _('Cron Schedule'),
1855 $ScheduledTask->get('minute'),
1856 $ScheduledTask->get('hour'),
1857 $ScheduledTask->get('dayOfMonth'),
1858 $ScheduledTask->get('month'),
1859 $ScheduledTask->get('dayOfWeek')
1860 );
1861 break;
1862 case 'single':
1863 $time = sprintf(
1864 '%s: %s',
1865 _('Delayed Start'),
1866 $scheduleDeployTime->format('Y-m-d H:i:s')
1867 );
1868 break;
1869 }
1870 echo '<div class="col-xs-9">';
1871 echo '<div class="panel panel-success">';
1872 echo '<div class="panel-heading text-center">';
1873 echo '<h4 class="title">';
1874 echo _('Tasked Successfully');
1875 echo '</h4>';
1876 echo '</div>';
1877 echo '<div class="panel-body text-center">';
1878 echo _('Task');
1879 echo ' ';
1880 echo $TaskType->get('name');
1881 echo ' ';
1882 echo _('Successfully created');
1883 echo '!';
1884 echo '</div>';
1885 echo '</div>';
1886 echo '<div class="panel panel-success">';
1887 echo '<div class="panel-heading text-center">';
1888 echo '<h4 class="title">';
1889 echo _('Created Tasks For');
1890 echo '</h4>';
1891 echo '</div>';
1892 echo '<div class="panel-body text-center">';
1893 echo '<ul class="nav nav-pills nav-stacked">';
1894 echo implode((array)$success);
1895 echo '</ul>';
1896 echo '</div>';
1897 echo '</div>';
1898 echo '</div>';
1899 }
1900 }
1901 /**
1902 * Presents the en-mass delete elements
1903 *
1904 * @return void
1905 */
1906 public function deletemulti()
1907 {
1908 global $sub;
1909 global $node;
1910 $this->title = sprintf(
1911 "%s's to remove",
1912 (
1913 $this->childClass !== 'Storage' ?
1914 $this->childClass :
1915 sprintf(
1916 '%s %s',
1917 $this->childClass,
1918 (
1919 $sub !== 'storageGroup' ?
1920 'Node' :
1921 'Group'
1922 )
1923 )
1924 )
1925 );
1926 if ('Storage' === $this->childClass) {
1927 if ('storageGroup' === $sub) {
1928 $this->childClass = 'StorageGroup';
1929 } else {
1930 $this->childClass = 'StorageNode';
1931 }
1932 }
1933 unset(
1934 $this->data,
1935 $this->form,
1936 $this->headerData,
1937 $this->templates,
1938 $this->attributes
1939 );
1940 $this->templates = array(
1941 '${field}',
1942 '${input}'
1943 );
1944 $this->attributes = array(
1945 array('class' => 'col-xs-4'),
1946 array('class' => 'col-xs-8 form-group')
1947 );
1948 $reqID = $node
1949 . 'IDArray';
1950 $items = filter_input(
1951 INPUT_POST,
1952 $reqID
1953 );
1954 $reqID = array_values(
1955 array_filter(
1956 array_unique(
1957 explode(',', $items)
1958 )
1959 )
1960 );
1961 Route::listem(
1962 $this->childClass,
1963 'name',
1964 false,
1965 ['id' => $reqID]
1966 );
1967 $items = json_decode(
1968 Route::getData()
1969 );
1970 $getme = strtolower($this->childClass).'s';
1971 $items = $items->$getme;
1972 foreach ((array)$items as &$object) {
1973 if ($getme == 'plugins') {
1974 if (!in_array($object->id, $reqID)) {
1975 continue;
1976 }
1977 }
1978 if ($object->protected) {
1979 continue;
1980 }
1981 $this->data[] = array(
1982 'field' => '<input type="hidden" value="'
1983 . $object->id
1984 . '" name="remitems[]"/>',
1985 'input' => '<a href="?node='
1986 . $node
1987 . '&sub=edit&id='
1988 . $object->id
1989 . '">'
1990 . $object->name
1991 . '</a>'
1992 );
1993 unset($object);
1994 }
1995 if (is_array($this->data) && count($this->data) < 1) {
1996 self::redirect('?node=' . $node);
1997 }
1998 $this->data[] = array(
1999 'field' => '<label for="delete">'
2000 . _('Remove these items?')
2001 . '</label>',
2002 'input' => '<button class="btn btn-danger btn-block" type="submit" '
2003 . 'name="delete" id="delete">'
2004 . _('Delete')
2005 . '</button>',
2006 );
2007 echo '<!-- Delete Items -->';
2008 echo '<div class="col-xs-9">';
2009 echo '<div class="panel panel-warning">';
2010 echo '<div class="panel-heading text-center">';
2011 echo '<h4 class="title">';
2012 echo $this->title;
2013 echo '</h4>';
2014 echo '</div>';
2015 echo '<div class="panel-body">';
2016 echo '<div id="deleteDiv"></div>';
2017 echo '<form class="form-horizontal" action="'
2018 . $this->formAction
2019 . '">';
2020 $this->render(12);
2021 echo '<input type="hidden" name="storagegroup" value="'
2022 . (
2023 $this->childClass === 'StorageGroup' ?
2024 1 :
2025 0
2026 )
2027 . '"/>';
2028 echo '</form>';
2029 echo '</div>';
2030 echo '</div>';
2031 echo '</div>';
2032 }
2033 /**
2034 * Actually performs the deletion actions
2035 *
2036 * @return void
2037 */
2038 public function deletemultiAjax()
2039 {
2040 if (self::getSetting('FOG_REAUTH_ON_DELETE')) {
2041 $user = filter_input(INPUT_POST, 'fogguiuser');
2042 $pass = filter_input(INPUT_POST, 'fogguipass');
2043 $validate = self::getClass('User')
2044 ->passwordValidate(
2045 $user,
2046 $pass,
2047 true
2048 );
2049 if (!$validate) {
2050 echo json_encode(
2051 array(
2052 'error' => self::$foglang['InvalidLogin'],
2053 'title' => _('Unable to Authenticate')
2054 )
2055 );
2056 exit;
2057 }
2058 }
2059 $remitems = filter_input_array(
2060 INPUT_POST,
2061 array(
2062 'remitems' => array(
2063 'flags' => FILTER_REQUIRE_ARRAY
2064 )
2065 )
2066 );
2067 $remitems = $remitems['remitems'];
2068 self::$HookManager->processEvent(
2069 'MULTI_REMOVE',
2070 array('removing' => &$remitems)
2071 );
2072 if ((int)$_POST['storagegroup'] === 1) {
2073 $this->childClass = 'StorageGroup';
2074 }
2075 self::getClass($this->childClass)
2076 ->getManager()
2077 ->destroy(
2078 array('id' => $remitems)
2079 );
2080 echo json_encode(
2081 array(
2082 'msg' => _('Successfully deleted'),
2083 'title' => _('Delete Success')
2084 )
2085 );
2086 exit;
2087 }
2088 /**
2089 * Displays the basic tasks
2090 *
2091 * @return void
2092 */
2093 public function basictasksOptions()
2094 {
2095 unset($this->headerData);
2096 $this->templates = array(
2097 '<a href="?node='
2098 . $this->node
2099 . '&sub=deploy&id=${'
2100 . $this->node
2101 . '_id}${task_id}"><i class="fa '
2102 . 'fa-${task_icon} fa-3x"></i><br/>'
2103 . '${task_name}</a>',
2104 '${task_desc}'
2105 );
2106 $this->attributes = array(
2107 array('class' => 'col-xs-4'),
2108 array('class' => 'col-xs-8')
2109 );
2110 $taskTypeIterator = function (&$TaskType) use (&$access, &$advanced) {
2111 if (!in_array($TaskType->access, $access)) {
2112 return;
2113 }
2114 if ($advanced != $TaskType->isAdvanced) {
2115 return;
2116 }
2117 $this->data[] = array(
2118 $this->node.'_id' => $this->obj->get('id'),
2119 'task_id' => '&type='.$TaskType->id,
2120 'task_icon' => $TaskType->icon,
2121 'task_name' => $TaskType->name,
2122 'task_desc' => $TaskType->description,
2123 );
2124 unset($TaskType);
2125 };
2126 Route::listem('tasktype', 'id');
2127 $items = json_decode(Route::getData());
2128 $items = $items->tasktypes;
2129 $advanced = 0;
2130 $access = array(
2131 'both',
2132 $this->node
2133 );
2134 foreach ((array)$items as $TaskType) {
2135 $taskTypeIterator($TaskType);
2136 unset($TaskType);
2137 }
2138 $this->data[] = array(
2139 $this->node.'_id' => $this->obj->get('id'),
2140 'task_id' => '#'
2141 . $this->node
2142 . '-tasks" class="advanced-tasks-link',
2143 'task_icon' => 'bars',
2144 'task_name' => _('Advanced'),
2145 'task_desc' => _('View advanced tasks for this')
2146 . ' '
2147 . $this->node
2148 . '.'
2149 );
2150 self::$HookManager->processEvent(
2151 sprintf(
2152 '%s_EDIT_TASKS',
2153 strtoupper($this->childClass)
2154 ),
2155 array(
2156 'headerData' => &$this->headerData,
2157 'data' => &$this->data,
2158 'templates' => &$this->templates,
2159 'attributes' => &$this->attributes
2160 )
2161 );
2162 echo '<!-- Taskings -->';
2163 echo '<div class="tab-pane fade" id="'
2164 . $this->node
2165 . '-tasks">';
2166 echo '<div class="panel panel-info">';
2167 echo '<div class="panel-heading text-center">';
2168 echo '<h4 class="title">';
2169 echo $this->childClass;
2170 echo ' ';
2171 echo _('Tasks');
2172 echo '</h4>';
2173 echo '</div>';
2174 echo '<div class="panel-body">';
2175 $this->render(12);
2176 echo '</div>';
2177 echo '</div>';
2178 echo '<div class="panel panel-info advanced-tasks">';
2179 echo '<div class="panel-heading text-center">';
2180 echo '<h4 class="title">';
2181 echo _('Advanced Actions');
2182 echo '</h4>';
2183 echo '</div>';
2184 echo '<div class="panel-body">';
2185 unset($this->data);
2186 $advanced = 1;
2187 foreach ((array)$items as &$TaskType) {
2188 $taskTypeIterator($TaskType);
2189 unset($TaskType);
2190 }
2191 self::$HookManager->processEvent(
2192 sprintf(
2193 '%s_DATA_ADV',
2194 strtoupper($this->node)
2195 ),
2196 array(
2197 'headerData' => &$this->headerData,
2198 'data' => &$this->data,
2199 'templates' => &$this->templates,
2200 'attributes' => &$this->attributes
2201 )
2202 );
2203 $this->render(12);
2204 echo '</div>';
2205 echo '</div>';
2206 echo '</div>';
2207 unset($TaskTypes);
2208 unset($this->data);
2209 }
2210 /**
2211 * Displays the AD options
2212 *
2213 * @param mixed $useAD whether to use ad or not
2214 * @param string $ADDomain the domain to select
2215 * @param string $ADOU the ou to select
2216 * @param string $ADUser the user to use
2217 * @param string $ADPass the password
2218 * @param string $ADPassLegacy the legacy password
2219 * @param mixed $enforce enforced selected
2220 * @param mixed $ownElement do we need to be our own container
2221 * @param mixed $retFields return just the fields?
2222 *
2223 * @return void
2224 */
2225 public function adFieldsToDisplay(
2226 $useAD = '',
2227 $ADDomain = '',
2228 $ADOU = '',
2229 $ADUser = '',
2230 $ADPass = '',
2231 $ADPassLegacy = '',
2232 $enforce = '',
2233 $ownElement = true,
2234 $retFields = false
2235 ) {
2236 global $node;
2237 global $sub;
2238 if ($this->obj->isValid()) {
2239 if (empty($useAD)) {
2240 $useAD = $this->obj->get('useAD');
2241 }
2242 if (empty($ADDomain)) {
2243 $ADDomain = $this->obj->get('ADDomain');
2244 }
2245 if (empty($ADOU)) {
2246 $ADOU = trim($this->obj->get('ADOU'));
2247 $ADOU = str_replace(';', '', $ADOU);
2248 }
2249 if (empty($ADUser)) {
2250 $ADUser = $this->obj->get('ADUser');
2251 }
2252 if (empty($ADPass)) {
2253 $ADPass = (
2254 $this->obj->get('ADPass') ?
2255 '********************************' :
2256 ''
2257 );
2258 }
2259 if (empty($ADPassLegacy)) {
2260 $ADPassLegacy = $this->obj->get('ADPassLegacy');
2261 }
2262 }
2263 $OUs = array_unique(
2264 array_filter(
2265 explode(
2266 '|',
2267 self::getSetting('FOG_AD_DEFAULT_OU')
2268 )
2269 )
2270 );
2271 $ADOU = trim($ADOU);
2272 $ADOU = str_replace(';', '', $ADOU);
2273 $optFound = $ADOU;
2274 if (is_array($OUs) && count($OUs) > 1) {
2275 ob_start();
2276 printf(
2277 '<option value="">- %s -</option>',
2278 self::$foglang['PleaseSelect']
2279 );
2280 foreach ((array)$OUs as &$OU) {
2281 $OU = trim($OU);
2282 $ou = str_replace(';', '', $OU);
2283 if (!$optFound && $ou === $ADOU) {
2284 $optFound = $ou;
2285 }
2286 if (!$optFound && false !== strpos($OU, ';')) {
2287 $optFound = $ou;
2288 }
2289 printf(
2290 '<option value="%s"%s>%s</option>',
2291 $ou,
2292 (
2293 $optFound === $ou ?
2294 ' selected' :
2295 ''
2296 ),
2297 $ou
2298 );
2299 }
2300 $OUOptions = sprintf(
2301 '<select id="adOU" class="form-control" name="ou">'
2302 . '%s</select>',
2303 ob_get_clean()
2304 );
2305 } else {
2306 $OUOptions = sprintf(
2307 '<input id="adOU" class="form-control" type="text" name='
2308 . '"ou" value="%s" autocomplete="off"/>',
2309 $ADOU
2310 );
2311 }
2312 $fields = array(
2313 '<label for="clearAD">'
2314 . _('Clear all fields?')
2315 . '</label>' => '<button class="btn btn-warning btn-block" '
2316 . 'type="button" id="clearAD">'
2317 . _('Clear Fields')
2318 . '</button>',
2319 sprintf(
2320 '<label for="adEnabled">%s</label>',
2321 _('Join Domain after deploy')
2322 ) => sprintf(
2323 '<input id="adEnabled" type="checkbox" name="domain"%s/>',
2324 (
2325 $useAD ?
2326 ' checked' :
2327 ''
2328 )
2329 ),
2330 sprintf(
2331 '<label for="adDomain">%s</label>',
2332 _('Domain name')
2333 ) => sprintf(
2334 '<div class="input-group">'
2335 . '<input id="adDomain" class="form-control" type="text" '
2336 . 'name="domainname" value="%s" autocomplete="off"/>'
2337 . '</div>',
2338 $ADDomain
2339 ),
2340 sprintf(
2341 '<label for="adOU">%s'
2342 . '<br/>(%s)'
2343 . '</label>',
2344 _('Organizational Unit'),
2345 _('Blank for default')
2346 ) => $OUOptions,
2347 sprintf(
2348 '<label for="adUsername">%s</label>',
2349 _('Domain Username')
2350 ) => sprintf(
2351 '<div class="input-group">'
2352 . '<input id="adUsername" class="form-control" type="text" '
2353 . 'name="domainuser" value="%s" autocomplete="off"/>'
2354 . '</div>',
2355 $ADUser
2356 ),
2357 sprintf(
2358 '<label for="adPassword">%s'
2359 . '</label>',
2360 _('Domain Password')
2361 ) => sprintf(
2362 '<div class="input-group">'
2363 . '<input id="adPassword" class="form-control" type='
2364 . '"password" '
2365 . 'name="domainpassword" value="%s" autocomplete="off"/>'
2366 . '</div>',
2367 $ADPass
2368 ),
2369 sprintf(
2370 '<label for="adPasswordLegacy">%s'
2371 . '<br/>(%s)'
2372 . '</label>',
2373 _('Domain Password Legacy'),
2374 _('Must be encrypted')
2375 ) => sprintf(
2376 '<div class="input-group">'
2377 . '<input id="adPasswordLegacy" class="form-control" '
2378 . 'type="password" name="domainpasswordlegacy" '
2379 . 'value="%s" autocomplete="off"/>'
2380 . '</div>',
2381 $ADPassLegacy
2382 ),
2383 sprintf(
2384 '<label for="ensel">'
2385 . '%s?'
2386 . '</label>',
2387 _('Name Change/AD Join Forced reboot')
2388 ) =>
2389 sprintf(
2390 '<input name="enforcesel" type="checkbox" id="'
2391 . 'ensel" autocomplete="off"%s/>',
2392 (
2393 $enforce ?
2394 ' checked' :
2395 ''
2396 )
2397 ),
2398 '<label for="'
2399 . $node
2400 . '-'
2401 . $sub
2402 . '">'
2403 . _('Make changes?')
2404 . '</label>' => '<button class="'
2405 . 'btn btn-info btn-block" type="submit" name='
2406 . '"updatead" id="'
2407 . $node
2408 . '-'
2409 . $sub
2410 . '">'
2411 . (
2412 $sub == 'add' ?
2413 _('Add') :
2414 _('Update')
2415 )
2416 . '</button>'
2417 );
2418 if ($retFields) {
2419 return $fields;
2420 }
2421 unset(
2422 $this->data,
2423 $this->headerData,
2424 $this->templates,
2425 $this->attributes
2426 );
2427 $this->templates = array(
2428 '${field}',
2429 '${input}',
2430 );
2431 $this->attributes = array(
2432 array('class' => 'col-xs-4'),
2433 array('class' => 'col-xs-8'),
2434 );
2435 array_walk($fields, $this->fieldsToData);
2436 self::$HookManager->processEvent(
2437 sprintf(
2438 '%s_EDIT_AD',
2439 strtoupper($this->childClass)
2440 ),
2441 array(
2442 'headerData' => &$this->headerData,
2443 'data' => &$this->data,
2444 'attributes' => &$this->attributes,
2445 'templates' => &$this->templates
2446 )
2447 );
2448 echo '<!-- Active Directory -->';
2449 if ($ownElement) {
2450 echo '<div id="'
2451 . $node
2452 . '-active-directory" class="tab-pane fade">';
2453 }
2454 echo '<div class="panel panel-info">';
2455 echo '<div class="panel-heading text-center">';
2456 echo '<h4 class="title text-center">';
2457 echo _('Active Directory');
2458 echo '</h4>';
2459 echo '</div>';
2460 echo '<div class="panel-body">';
2461 if ($ownElement) {
2462 echo '<form class="form-horizontal" method="post" action="'
2463 . $this->formAction
2464 . '&tab='
2465 . $node
2466 . '-active-directory'
2467 . '">';
2468 }
2469 echo '<input type="text" name="fakeusernameremembered" class='
2470 . '"fakes hidden"/>';
2471 echo '<input type="password" name="fakepasswordremembered" class='
2472 . '"fakes hidden"/>';
2473 $this->render(12);
2474 if ($ownElement) {
2475 echo '</form>';
2476 }
2477 echo '</div>';
2478 echo '</div>';
2479 if ($ownElement) {
2480 echo '</div>';
2481 }
2482 unset($this->data);
2483 }
2484 /**
2485 * Get's the adinformation from ajax
2486 *
2487 * @return void
2488 */
2489 public function adInfo()
2490 {
2491 if (!self::$ajax) {
2492 return;
2493 }
2494 $items = array(
2495 'DOMAINNAME',
2496 'OU',
2497 'PASSWORD',
2498 'PASSWORD_LEGACY',
2499 'USER',
2500 );
2501 $names = array();
2502 foreach ((array)$items as &$item) {
2503 $names[] = sprintf(
2504 'FOG_AD_DEFAULT_%s',
2505 $item
2506 );
2507 unset($item);
2508 }
2509 list(
2510 $domainname,
2511 $ou,
2512 $password,
2513 $password_legacy,
2514 $user
2515 ) = self::getSubObjectIDs(
2516 'Service',
2517 array('name' => $names),
2518 'value',
2519 false,
2520 'AND',
2521 'name',
2522 false,
2523 ''
2524 );
2525 echo json_encode(
2526 array(
2527 'domainname' => $domainname,
2528 'ou' => $ou,
2529 'domainpass' => $password,
2530 'domainpasslegacy' => $password_legacy,
2531 'domainuser' => $user,
2532 )
2533 );
2534 exit;
2535 }
2536 /**
2537 * Fetches the kernels
2538 *
2539 * @return mixed
2540 */
2541 public function kernelfetch()
2542 {
2543 try {
2544 $msg = filter_input(INPUT_POST, 'msg');
2545 if ($_SESSION['allow_ajax_kdl']
2546 && $_SESSION['dest-kernel-file']
2547 && $_SESSION['tmp-kernel-file']
2548 && $_SESSION['dl-kernel-file']
2549 ) {
2550 if ($msg == 'dl') {
2551 $fh = fopen(
2552 $_SESSION['tmp-kernel-file'],
2553 'wb'
2554 );
2555 if ($fh === false) {
2556 throw new Exception(
2557 _('Error: Failed to open temp file')
2558 );
2559 }
2560 self::$FOGURLRequests->process(
2561 $_SESSION['dl-kernel-file'],
2562 'GET',
2563 false,
2564 false,
2565 false,
2566 false,
2567 $fh
2568 );
2569 if (!file_exists($_SESSION['tmp-kernel-file'])) {
2570 throw new Exception(
2571 _('Error: Failed to download kernel')
2572 );
2573 }
2574 $filesize = self::getFilesize(
2575 $_SESSION['tmp-kernel-file']
2576 );
2577 if ($filesize < 1048576) {
2578 throw new Exception(
2579 sprintf(
2580 '%s: %s: %s - %s',
2581 _('Error'),
2582 _('Download Failed'),
2583 _('Failed'),
2584 _('filesize'),
2585 $filesize
2586 )
2587 );
2588 }
2589 die('##OK##');
2590 } elseif ($msg == 'tftp') {
2591 $destfile = $_SESSION['dest-kernel-file'];
2592 $tmpfile = $_SESSION['tmp-kernel-file'];
2593 unset(
2594 $_SESSION['dest-kernel-file'],
2595 $_SESSION['tmp-kernel-file'],
2596 $_SESSION['dl-kernel-file']
2597 );
2598 $orig = sprintf(
2599 '/%s/%s',
2600 trim(self::getSetting('FOG_TFTP_PXE_KERNEL_DIR'), '/'),
2601 $destfile
2602 );
2603 $backuppath = sprintf(
2604 '/%s/backup/',
2605 dirname($orig)
2606 );
2607 $backupfile = sprintf(
2608 '%s%s_%s',
2609 $backuppath,
2610 $destfile,
2611 self::formatTime('', 'Ymd_His')
2612 );
2613 list(
2614 $tftpPass,
2615 $tftpUser,
2616 $tftpHost
2617 ) = self::getSubObjectIDs(
2618 'Service',
2619 array(
2620 'name' => array(
2621 'FOG_TFTP_FTP_PASSWORD',
2622 'FOG_TFTP_FTP_USERNAME',
2623 'FOG_TFTP_HOST'
2624 )
2625 ),
2626 'value',
2627 false,
2628 'AND',
2629 'name',
2630 false,
2631 ''
2632 );
2633 self::$FOGFTP
2634 ->set('host', $tftpHost)
2635 ->set('username', $tftpUser)
2636 ->set('password', $tftpPass)
2637 ->connect();
2638 if (!self::$FOGFTP->exists($backuppath)) {
2639 self::$FOGFTP->mkdir($backuppath);
2640 }
2641 if (self::$FOGFTP->exists($orig)) {
2642 self::$FOGFTP->rename($orig, $backupfile);
2643 }
2644 self::$FOGFTP
2645 ->delete($orig)
2646 ->rename($tmpfile, $orig)
2647 ->chmod(0755, $orig)
2648 ->close();
2649 unlink($tmpfile);
2650 die('##OK##');
2651 }
2652 }
2653 } catch (Exception $e) {
2654 echo $e->getMessage();
2655 }
2656 self::$FOGFTP->close();
2657 }
2658 /**
2659 * Hands out the login information
2660 * such as version and number of users
2661 *
2662 * @return void
2663 */
2664 public function loginInfo()
2665 {
2666 $stable = '';
2667 $development = '';
2668 $urls = array(
2669 'https://fogproject.org/globalusers',
2670 'https://api.github.com/repos/fogproject/fogproject/tags',
2671 'https://raw.githubusercontent.com/FOGProject/fogproject/dev-branch/packages/web/lib/fog/system.class.php'
2672 );
2673 $resp = self::$FOGURLRequests->process($urls);
2674 $data['sites'] = array_shift($resp);
2675 $tags = json_decode(array_shift($resp));
2676 $systemclass = array_shift($resp);
2677 foreach ($tags as $tag) {
2678 if (preg_match('/^[0-9]\.[0-9]\.[0-9]$/', $tag->name)) {
2679 $stable = $tag->name;
2680 break;
2681 }
2682 }
2683 if (preg_match("/FOG_VERSION', '([0-9.RCalphbet-]*)'/", $systemclass, $fogver)) {
2684 $development = $fogver[1];
2685 }
2686 $data['version'] = json_encode(array('stable' => $stable, 'dev' => $development));
2687 echo json_encode($data);
2688 exit;
2689 }
2690 /**
2691 * Gets the associated info from the mac addresses
2692 *
2693 * @return void
2694 */
2695 public function getmacman()
2696 {
2697 try {
2698 if (!self::getMACLookupCount()) {
2699 throw new Exception(
2700 sprintf(
2701 '<a href="?node=about&sub=maclist">%s</a>',
2702 _('Load MAC Vendors')
2703 )
2704 );
2705 }
2706 $pref = filter_input(INPUT_GET, 'prefix');
2707 $MAC = self::getClass('MACAddress', $pref);
2708 $prefix = $MAC->getMACPrefix();
2709 if (!$MAC->isValid() || !$prefix) {
2710 throw new Exception(_('Unknown'));
2711 }
2712 $OUI = self::getClass('OUIManager')->find(array('prefix'=>$prefix));
2713 $OUI = array_shift($OUI);
2714 if (!(($OUI instanceof OUI) && $OUI->isValid())) {
2715 throw new Exception(_('Not found'));
2716 }
2717 $Data = sprintf('%s', $OUI->get('name'));
2718 } catch (Exception $e) {
2719 $Data = sprintf('%s', $e->getMessage());
2720 }
2721 echo $Data;
2722 exit;
2723 }
2724 /**
2725 * Presents the delete page for the object
2726 *
2727 * @return void
2728 */
2729 public function delete()
2730 {
2731 $this->title = sprintf(
2732 '%s: %s',
2733 _('Remove'),
2734 $this->obj->get('name')
2735 );
2736 unset($this->headerData);
2737 $this->attributes = array(
2738 array('class' => 'col-xs-4'),
2739 array('class' => 'col-xs-8 form-group'),
2740 );
2741 $this->templates = array(
2742 '${field}',
2743 '${input}',
2744 );
2745 if ($this->obj instanceof Group) {
2746 $fieldsg = array(
2747 '<label for="massDel">'
2748 . _('Delete hosts within')
2749 . '</label>' => '<div class="input-group checkbox">'
2750 . '<input type="checkbox" name="massDelHosts" id="'
2751 . 'massDel"/>'
2752 . '</div>'
2753 );
2754 } elseif ($this->obj instanceof Image || $this->obj instanceof Snapin) {
2755 $fieldsi = array(
2756 '<label for="andFile">'
2757 . _('Delete files')
2758 . '</label>' => '<div class="input-group checkbox">'
2759 . '<input type="checkbox" name="andFile" id="'
2760 . 'andFile"/>'
2761 . '</div>'
2762 );
2763 }
2764 $fields = self::fastmerge(
2765 (array)$fieldsg,
2766 (array)$fieldsi,
2767 array(
2768 '<label for="delete">'
2769 . $this->title
2770 . '</label>' => '<input type="hidden" name="remitems[]" '
2771 . 'value="'
2772 . $this->obj->get('id')
2773 . '"/>'
2774 . '<button type="submit" name="delete" id="delete" '
2775 . 'class="btn btn-danger btn-block">'
2776 . _('Delete')
2777 . '</button>'
2778 )
2779 );
2780 $fields = array_filter($fields);
2781 self::$HookManager->processEvent(
2782 sprintf(
2783 '%s_DEL_FIELDS',
2784 strtoupper($this->node)
2785 ),
2786 array(
2787 'fields' => &$fields,
2788 $this->childClass => &$this->obj
2789 )
2790 );
2791 array_walk($fields, $this->fieldsToData);
2792 self::$HookManager->processEvent(
2793 sprintf(
2794 '%S_DEL',
2795 strtoupper($this->childClass)
2796 ),
2797 array(
2798 'data' => &$this->data,
2799 'headerData' => &$this->headerData,
2800 'templates' => &$this->templates,
2801 'attributes' => &$this->attributes,
2802 $this->childClass => &$this->obj
2803 )
2804 );
2805 echo '<div class="col-xs-9">';
2806 echo '<div class="panel panel-warning">';
2807 echo '<div class="panel-heading text-center">';
2808 echo '<h4 class="title">';
2809 echo $this->title;
2810 echo '</h4>';
2811 echo '</div>';
2812 echo '<div class="panel-body">';
2813 echo '<div id="deleteDiv"></div>';
2814 echo '<form class="form-horizontal" method="post" action="'
2815 . $this->formAction
2816 . '">';
2817 $this->render(12);
2818 echo '</form>';
2819 echo '</div>';
2820 echo '</div>';
2821 echo '</div>';
2822 }
2823 /**
2824 * Sends the new client the configuration options
2825 *
2826 * @return void
2827 */
2828 public function configure()
2829 {
2830 $Services = self::getSubObjectIDs(
2831 'Service',
2832 array(
2833 'name' => array(
2834 'FOG_CLIENT_CHECKIN_TIME',
2835 'FOG_CLIENT_MAXSIZE',
2836 'FOG_GRACE_TIMEOUT',
2837 'FOG_TASK_FORCE_REBOOT'
2838 )
2839 ),
2840 'value',
2841 false,
2842 'AND',
2843 'name',
2844 false,
2845 ''
2846 );
2847 printf(
2848 "#!ok\n"
2849 . "#sleep=%d\n"
2850 . "#maxsize=%d\n"
2851 . "#promptTime=%d\n"
2852 . "#force=%s",
2853 array_shift($Services) + mt_rand(1, 91),
2854 array_shift($Services),
2855 array_shift($Services),
2856 array_shift($Services)
2857 );
2858 exit;
2859 }
2860 /**
2861 * Authorizes the client with the server
2862 *
2863 * @return void
2864 */
2865 public function authorize()
2866 {
2867 try {
2868 self::getHostItem(true);
2869 $sym_key = filter_input(INPUT_POST, 'sym_key');
2870 if (!$sym_key) {
2871 $sym_key = filter_input(INPUT_GET, 'sym_key');
2872 }
2873 $token = filter_input(INPUT_POST, 'token');
2874 if (!$token) {
2875 $token = filter_input(INPUT_GET, 'token');
2876 }
2877 $data = array_values(
2878 array_map(
2879 'bin2hex',
2880 self::certDecrypt(
2881 array(
2882 $sym_key,
2883 $token
2884 )
2885 )
2886 )
2887 );
2888 $key = $data[0];
2889 $token = $data[1];
2890 if (self::$Host->get('sec_tok')
2891 && $token !== self::$Host->get('sec_tok')
2892 ) {
2893 self::$Host
2894 ->set(
2895 'pub_key',
2896 null
2897 )->save()->load();
2898 throw new Exception('#!ist');
2899 }
2900 if (self::$Host->get('sec_tok')
2901 && !$key
2902 ) {
2903 throw new Exception('#!ihc');
2904 }
2905 $expire = self::niceDate(self::$Host->get('sec_time'));
2906 if (self::niceDate() > $expire
2907 || !trim(self::$Host->get('pub_key'))
2908 ) {
2909 self::$Host
2910 ->set(
2911 'sec_time',
2912 self::niceDate()
2913 ->modify('+30 minutes')
2914 ->format('Y-m-d H:i:s')
2915 )
2916 ->set(
2917 'sec_tok',
2918 self::createSecToken()
2919 );
2920 }
2921 self::$Host
2922 ->set('pub_key', $key)
2923 ->save();
2924 $vals['token'] = self::$Host->get('sec_tok');
2925 if (self::$json === true) {
2926 printf(
2927 '#!en=%s',
2928 self::certEncrypt(
2929 json_encode($vals)
2930 )
2931 );
2932 exit;
2933 }
2934 printf(
2935 '#!en=%s',
2936 self::certEncrypt(
2937 "#!ok\n#token=" . self::$Host->get('sec_tok')
2938 )
2939 );
2940 } catch (Exception $e) {
2941 if (self::$json === true) {
2942 if ($e->getMessage() == '#!ihc') {
2943 die($e->getMessage());
2944 }
2945 $err = str_replace('#!', '', $e->getMessage());
2946 echo json_encode(
2947 array('error' => $err)
2948 );
2949 exit;
2950 }
2951 if ($e->getMessage() == '#!ist') {
2952 echo json_encode(
2953 array('error' => 'ist')
2954 );
2955 exit;
2956 }
2957 echo $e->getMessage();
2958 }
2959 exit;
2960 }
2961 /**
2962 * Used by the new client and collects
2963 * all the information at once. This
2964 * allows the client to do much less polls
2965 * to the server.
2966 *
2967 * @return void
2968 */
2969 public function requestClientInfo()
2970 {
2971 if (isset($_POST['configure'])
2972 || isset($_GET['configure'])
2973 ) {
2974 list(
2975 $bannerimg,
2976 $bannersha,
2977 $checkin,
2978 $maxsize,
2979 $pcolor,
2980 $coname,
2981 $timeout,
2982 $freboot
2983 ) = self::getSubObjectIDs(
2984 'Service',
2985 array(
2986 'name' => array(
2987 'FOG_CLIENT_BANNER_IMAGE',
2988 'FOG_CLIENT_BANNER_SHA',
2989 'FOG_CLIENT_CHECKIN_TIME',
2990 'FOG_CLIENT_MAXSIZE',
2991 'FOG_COMPANY_COLOR',
2992 'FOG_COMPANY_NAME',
2993 'FOG_GRACE_TIMEOUT',
2994 'FOG_TASK_FORCE_REBOOT'
2995 )
2996 ),
2997 'value',
2998 false,
2999 'AND',
3000 'name',
3001 false,
3002 ''
3003 );
3004 $vals = array(
3005 'sleep' => $checkin + mt_rand(1, 91),
3006 'maxsize' => $maxsize,
3007 'promptTime' => $timeout,
3008 'force' => (bool)$freboot,
3009 'bannerURL' => (
3010 $bannerimg ?
3011 sprintf(
3012 '/management/other/%s',
3013 $bannerimg
3014 ) :
3015 ''
3016 ),
3017 'bannerHash' => strtoupper($bannersha),
3018 'color' => "#$pcolor",
3019 'company' => $coname
3020 );
3021 echo json_encode($vals);
3022 exit;
3023 }
3024 if (isset($_POST['authorize'])
3025 || isset($_GET['authorize'])
3026 ) {
3027 $this->authorize(true);
3028 }
3029 // Handles adding additional system macs for us.
3030 ob_start();
3031 self::getClass('RegisterClient')->json();
3032 ob_end_clean();
3033 try {
3034 $igMods = array(
3035 'dircleanup',
3036 'usercleanup',
3037 'clientupdater',
3038 'hostregister',
3039 );
3040 $globalModules = array_diff(
3041 self::getGlobalModuleStatus(false, true),
3042 array(
3043 'dircleanup',
3044 'usercleanup',
3045 'clientupdater',
3046 'hostregister'
3047 )
3048 );
3049 $globalInfo = self::getGlobalModuleStatus();
3050 $globalDisabled = array();
3051 foreach ((array)$globalInfo as $key => &$en) {
3052 if (in_array($key, $igMods)) {
3053 continue;
3054 }
3055 if (!$en) {
3056 $globalDisabled[] = $key;
3057 }
3058 unset($key, $en);
3059 }
3060 self::getHostItem(
3061 true,
3062 false,
3063 false,
3064 false,
3065 self::$newService || self::$json
3066 );
3067 $hostModules = self::getSubObjectIDs(
3068 'Module',
3069 array('id' => self::$Host->get('modules')),
3070 'shortName'
3071 );
3072 $hostEnabled = array_diff(
3073 (array)$hostModules,
3074 (array)$igMods
3075 );
3076 $hostDisabled = array_diff(
3077 (array)$globalModules,
3078 (array)$hostEnabled
3079 );
3080 $array = array();
3081 foreach ($globalModules as $index => &$key) {
3082 switch ($key) {
3083 case 'greenfog':
3084 $class='GF';
3085 continue 2;
3086 case 'powermanagement':
3087 $class='PM';
3088 break;
3089 case 'printermanager':
3090 $class='PrinterClient';
3091 break;
3092 case 'taskreboot':
3093 $class='Jobs';
3094 break;
3095 case 'usertracker':
3096 $class='UserTrack';
3097 break;
3098 default:
3099 $class=$key;
3100 break;
3101 }
3102 $disabled = in_array(
3103 $key,
3104 self::fastmerge(
3105 (array)$globalDisabled,
3106 (array)$hostDisabled
3107 )
3108 );
3109 if ($disabled) {
3110 if (in_array($key, $globalDisabled)) {
3111 $array[$key]['error'] = 'ng';
3112 } elseif (in_array($key, $hostDisabled)) {
3113 $array[$key]['error'] = 'nh';
3114 }
3115 } else {
3116 $array[$key] = self::getClass(
3117 $class,
3118 true,
3119 false,
3120 false,
3121 false,
3122 self::$newService || self::$json
3123 )->json();
3124 }
3125 unset($key);
3126 }
3127 //echo json_encode($array, JSON_UNESCAPED_UNICODE);
3128
3129 self::$HookManager->processEvent(
3130 'REQUEST_CLIENT_INFO',
3131 array(
3132 'repFields' => &$array,
3133 'Host' => self::$Host
3134 )
3135 );
3136
3137 $this->sendData(
3138 json_encode(
3139 $array,
3140 JSON_UNESCAPED_UNICODE
3141 ),
3142 true,
3143 $array
3144 );
3145 } catch (Exception $e) {
3146 echo $e->getMessage();
3147 }
3148 exit;
3149 }
3150 /**
3151 * Clears the Host's AES information. Used
3152 * by the button to clear fields and reset
3153 * encryption as well
3154 *
3155 * @return void
3156 */
3157 public function clearAES()
3158 {
3159 global $groupid;
3160 global $id;
3161 if (!(is_numeric($groupid) || is_numeric($id))) {
3162 return;
3163 }
3164 if ($id < 1 && $groupid < 1) {
3165 return;
3166 }
3167 if ($groupid < 1) {
3168 $hosts = $id;
3169 } else {
3170 $hosts = self::getClass('Group', $groupid)
3171 ->get('hosts');
3172 }
3173 self::getClass('HostManager')
3174 ->update(
3175 array('id' => $hosts),
3176 '',
3177 array(
3178 'pub_key' => '',
3179 'sec_tok' => '',
3180 'sec_time' => '0000-00-00 00:00:00'
3181 )
3182 );
3183 }
3184 /**
3185 * Clears group Powermanagement tasks
3186 *
3187 * @return void
3188 */
3189 public function clearPMTasks()
3190 {
3191 global $groupid;
3192 if (!is_numeric($groupid)) {
3193 return;
3194 }
3195 if ($groupid < 1) {
3196 return;
3197 }
3198 $hosts = self::getClass('Group', $groupid)
3199 ->get('hosts');
3200 self::getClass('PowerManagementManager')
3201 ->destroy(
3202 array('hostID' => $hosts)
3203 );
3204 }
3205 /**
3206 * Perform the actual delete
3207 *
3208 * @return void
3209 */
3210 public function deletePost()
3211 {
3212 if (self::getSetting('FOG_REAUTH_ON_DELETE')) {
3213 $validate = self::getClass('User')
3214 ->passwordValidate(
3215 $_POST['fogguiuser'],
3216 $_POST['fogguipass'],
3217 true
3218 );
3219 if (!$validate) {
3220 echo json_encode(
3221 array(
3222 'error' => self::$foglang['InvalidLogin']
3223 )
3224 );
3225 exit;
3226 }
3227 }
3228 self::$HookManager->processEvent(
3229 sprintf(
3230 '%s_DEL_POST',
3231 strtoupper($this->node)
3232 ),
3233 array($this->childClass => &$this->obj)
3234 );
3235 try {
3236 if ($this->obj->get('protected')) {
3237 throw new Exception(
3238 sprintf(
3239 '%s %s',
3240 $this->childClass,
3241 _('is protected, removal not allowed')
3242 )
3243 );
3244 }
3245 if ($this->obj instanceof Group) {
3246 if (isset($_POST['massDelHosts'])) {
3247 self::getClass('HostManager')
3248 ->destroy(
3249 array('id' => $this->obj->get('hosts'))
3250 );
3251 }
3252 }
3253 if (isset($_POST['andFile'])) {
3254 $this->obj->deleteFile();
3255 }
3256 if (!$this->obj->destroy()) {
3257 throw new Exception(
3258 _('Failed to destroy')
3259 );
3260 }
3261 self::$HookManager->processEvent(
3262 sprintf(
3263 '%s_DELETE_SUCCESS',
3264 strtoupper($this->childClass)
3265 ),
3266 array($this->childClass => &$this->obj)
3267 );
3268 self::resetRequest();
3269 echo json_encode(
3270 array(
3271 'msg' => sprintf(
3272 '%s %s: %s',
3273 $this->childClass,
3274 _('deleted'),
3275 $this->obj->get('name')
3276 ),
3277 'title' => _('Delete Success')
3278 )
3279 );
3280 exit;
3281 } catch (Exception $e) {
3282 self::$HookManager->processEvent(
3283 sprintf(
3284 '%s_DELETE_FAIL',
3285 strtoupper($this->node)
3286 ),
3287 array($this->childClass => &$this->obj)
3288 );
3289 echo json_encode(
3290 array(
3291 'error' => $e->getMessage(),
3292 'title' => _('Delete Fail')
3293 )
3294 );
3295 exit;
3296 }
3297 }
3298 /**
3299 * Resents the page's search elements
3300 *
3301 * @return void
3302 */
3303 public function search()
3304 {
3305 $eventClass = $this->childClass;
3306 if ($this->childClass == 'Task') {
3307 $eventClass = 'host';
3308 }
3309 $this->title = _('Search')
3310 . ' '
3311 . $this->node
3312 . "s";
3313 self::$HookManager->processEvent(
3314 sprintf(
3315 '%s_DATA',
3316 strtoupper($eventClass)
3317 ),
3318 array(
3319 'data' => &$this->data,
3320 'templates' => &$this->templates,
3321 'headerData' => &$this->headerData,
3322 'attributes' => &$this->attributes,
3323 'title' => &$this->title,
3324 )
3325 );
3326 self::$HookManager->processEvent(
3327 sprintf(
3328 '%s_HEADER_DATA',
3329 strtoupper($this->childClass)
3330 ),
3331 array('headerData' => &$this->headerData)
3332 );
3333 echo '<div class="col-xs-9">';
3334 echo '<div class="panel panel-info">';
3335 echo '<div class="panel-heading text-center">';
3336 echo '<h4 class="title">';
3337 echo $this->title;
3338 echo '</h4>';
3339 echo '</div>';
3340 echo '<div class="panel-body">';
3341 $this->render(12);
3342 echo '</div>';
3343 }
3344 /**
3345 * Search form submission
3346 *
3347 * @return void
3348 */
3349 public function searchPost()
3350 {
3351 $this->data = array();
3352 $manager = sprintf(
3353 '%sManager',
3354 $this->childClass
3355 );
3356 Route::search(
3357 $this->childClass,
3358 filter_input(INPUT_POST, 'crit')
3359 );
3360 $items = json_decode(Route::getData());
3361 $type = $this->node
3362 .'s';
3363 $search = $items->$type;
3364 if (is_array($search) && count($search) > 0) {
3365 array_walk($search, static::$returnData);
3366 }
3367 $event = sprintf(
3368 '%s_DATA',
3369 strtoupper($this->node)
3370 );
3371 self::$HookManager->processEvent(
3372 $event,
3373 array(
3374 'data' => &$this->data,
3375 'templates' => &$this->templates,
3376 'attributes' => &$this->attributes,
3377 'headerData' => &$this->headerData
3378 )
3379 );
3380 $event = sprintf(
3381 '%s_HEADER_DATA',
3382 strtoupper($this->node)
3383 );
3384 self::$HookManager->processEvent(
3385 $event,
3386 array(
3387 'headerData' => &$this->headerData
3388 )
3389 );
3390 $this->render();
3391 unset(
3392 $this->headerData,
3393 $this->data,
3394 $this->templates,
3395 $this->attributes
3396 );
3397 }
3398 /**
3399 * Presents the membership information
3400 *
3401 * @return void
3402 */
3403 public function membership()
3404 {
3405 $objType = $this->obj instanceof Host ? 'group' : 'host';
3406 unset(
3407 $this->data,
3408 $this->form,
3409 $this->headerData,
3410 $this->templates,
3411 $this->attributes
3412 );
3413 $this->headerData = array(
3414 '<label for="toggler">'
3415 . '<input type="checkbox" name="toggle-checkbox'
3416 . $this->node
3417 . '1" class="toggle-checkbox1" id="toggler"/>'
3418 . '</label>',
3419 _(ucfirst($objType) . ' Name')
3420 );
3421 $this->templates = array(
3422 '<label for="host-${host_id}">'
3423 . '<input type="checkbox" name="host[]" class="toggle-'
3424 . $objType
3425 . '${check_num}" id="host-${host_id}" '
3426 . 'value="${host_id}"/>'
3427 . '</label>',
3428 '<a href="?node='
3429 . $objType
3430 . '&sub=edit&id=${host_id}">${host_name}</a>'
3431 );
3432 $this->attributes = array(
3433 array(
3434 'width' => 16,
3435 'class' => 'filter-false'
3436 ),
3437 array(
3438 'data-toggle' => 'tooltip',
3439 'data-placement' => 'bottom',
3440 'title' => _('Edit')
3441 . ' '
3442 . '${host_name}'
3443 )
3444 );
3445 $getType = $objType . 's';
3446 $getter = $getType . 'notinme';
3447 Route::names(
3448 $objType,
3449 ['id' => $this->obj->get($getter)]
3450 );
3451 $namesnotinme = json_decode(
3452 Route::getData()
3453 );
3454 Route::names(
3455 $objType,
3456 ['id' => $this->obj->get($getType)]
3457 );
3458 $namesinme = json_decode(
3459 Route::getData()
3460 );
3461 foreach ($namesnotinme as &$item) {
3462 $this->data[] = [
3463 'host_id' => $item->id,
3464 'host_name' => $item->name,
3465 'check_num' => 1
3466 ];
3467 unset($item);
3468 }
3469 echo '<!-- Membership -->';
3470 echo '<div class="col-xs-9">';
3471 echo '<div class="tab-pane fade in active" id="'
3472 . $this->node
3473 . '-membership">';
3474 echo '<div class="panel panel-info">';
3475 echo '<div class="panel-heading text-center">';
3476 echo '<h4 class="title">';
3477 echo $this->childClass
3478 . ' '
3479 . _('Membership');
3480 echo '</h4>';
3481 echo '</div>';
3482 echo '<div class="panel-body">';
3483 echo '<form class="form-horizontal" method="post" action="'
3484 . $this->formAction
3485 . '">';
3486 if (count($this->data ?: []) > 0) {
3487 $notInMe = $meShow = $objType;
3488 $meShow .= 'MeShow';
3489 $notInMe .= 'NotInMe';
3490 echo '<div class="text-center">';
3491 echo '<div class="checkbox">';
3492 echo '<label for="'
3493 . $meShow
3494 . '">';
3495 echo '<input type="checkbox" name="'
3496 . $meShow
3497 . '" id="'
3498 . $meShow
3499 . '"/>';
3500 echo _("Check here to see what $getType can be added");
3501 echo '</label>';
3502 echo '</div>';
3503 echo '</div>';
3504 echo '<br/>';
3505 echo '<div class="hiddeninitially panel panel-info" id="'
3506 . $notInMe
3507 . '">';
3508 echo '<div class="panel-heading text-center">';
3509 echo '<h4 class="title">';
3510 echo _('Add')
3511 . ' '
3512 . ucfirst($getType);
3513 echo '</h4>';
3514 echo '</div>';
3515 echo '<div class="panel-body">';
3516 $this->render(12);
3517 echo '<div class="form-group">';
3518 echo '<label for="update'
3519 . $getType
3520 . '" class="control-label col-xs-4">';
3521 echo _("Add selected $getType");
3522 echo '</label>';
3523 echo '<div class="col-xs-8">';
3524 echo '<button type="submit" name="addHosts" '
3525 . 'id="update'
3526 . $getType
3527 . '" class="btn btn-info btn-block">'
3528 . _('Add')
3529 . '</button>';
3530 echo '</div>';
3531 echo '</div>';
3532 echo '</div>';
3533 echo '</div>';
3534 }
3535 unset(
3536 $this->data,
3537 $this->form,
3538 $this->headerData,
3539 $this->templates
3540 );
3541 $this->headerData = array(
3542 '<label for="toggler1">'
3543 . '<input type="checkbox" name="toggle-checkbox" '
3544 . 'class="toggle-checkboxAction" id="toggler1"/></label>',
3545 _(ucfirst($objType) . ' Name')
3546 );
3547 $this->templates = array(
3548 '<label for="hostrm-${host_id}">'
3549 . '<input type="checkbox" name="hostdel[]" '
3550 . 'value="${host_id}" class="toggle-action" id="'
3551 . 'hostrm-${host_id}"/>'
3552 . '</label>',
3553 '<a href="?node='
3554 . $objType
3555 . '&sub=edit&id=${host_id}">${host_name}</a>'
3556 );
3557 foreach ((array)$namesinme as $item) {
3558 $this->data[] = [
3559 'host_id' => $item->id,
3560 'host_name' => $item->name,
3561 'check_num' => 1
3562 ];
3563 unset($item);
3564 }
3565 if (count($this->data ?: []) > 0) {
3566 echo '<div class="panel panel-warning">';
3567 echo '<div class="panel-heading text-center">';
3568 echo '<h4 class="title">';
3569 echo _('Remove ' . ucfirst($getType));
3570 echo '</h4>';
3571 echo '</div>';
3572 echo '<div class="panel-body">';
3573 $this->render(12);
3574 echo '<div class="form-group">';
3575 echo '<label for="remhosts" class="control-label col-xs-4">';
3576 echo _('Remove selected ' . $getType);
3577 echo '</label>';
3578 echo '<div class="col-xs-8">';
3579 echo '<button type="submit" name="remhosts" class='
3580 . '"btn btn-danger btn-block" id="remhosts">'
3581 . _('Remove')
3582 . '</button>';
3583 echo '</div>';
3584 echo '</div>';
3585 echo '</div>';
3586 echo '</div>';
3587 }
3588 echo '</form>';
3589 echo '</div>';
3590 echo '</div>';
3591 echo '</div>';
3592 echo '</div>';
3593 }
3594 /**
3595 * Commonized membership actions
3596 *
3597 * @return void
3598 */
3599 public function membershipPost()
3600 {
3601 if (self::$ajax) {
3602 return;
3603 }
3604 $reqitems = filter_input_array(
3605 INPUT_POST,
3606 array(
3607 'host' => array(
3608 'flags' => FILTER_REQUIRE_ARRAY
3609 ),
3610 'hostdel' => array(
3611 'flags' => FILTER_REQUIRE_ARRAY
3612 )
3613 )
3614 );
3615 $host = $reqitems['host'];
3616 $hostdel = $reqitems['hostdel'];
3617 if (isset($_POST['addHosts'])) {
3618 $this->obj->addHost($host);
3619 }
3620 if (isset($_POST['remhosts'])) {
3621 $this->obj->removeHost($hostdel);
3622 }
3623 if ($this->obj->save()) {
3624 self::redirect($this->formAction);
3625 }
3626 }
3627 /**
3628 * Perform wakeup stuff
3629 *
3630 * @return void
3631 */
3632 public function wakeEmUp()
3633 {
3634 $mac = filter_input(INPUT_POST, 'mac');
3635 if (!$mac) {
3636 $mac = filter_input(INPUT_GET, 'mac');
3637 }
3638 $macs = self::parseMacList($mac);
3639 if (is_array($macs) && count($macs) < 1) {
3640 return;
3641 }
3642 self::getClass('WakeOnLan', implode('|', $macs))->send();
3643 }
3644 /**
3645 * Presents the relevant class items for export
3646 *
3647 * @return void
3648 */
3649 public function export()
3650 {
3651 $this->title = sprintf(
3652 'Export %s',
3653 $this->childClass
3654 );
3655 unset(
3656 $this->data,
3657 $this->form,
3658 $this->headerData,
3659 $this->templates,
3660 $this->attributes
3661 );
3662 $this->attributes = array(
3663 array('class' => 'col-xs-4'),
3664 array('class' => 'col-xs-8'),
3665 );
3666 $this->templates = array(
3667 '${field}',
3668 '${input}',
3669 );
3670 $fields = array(
3671 '<label for="exportbtn">'
3672 . _('Export CSV')
3673 . '</label>' => '<div id="exportDiv"></div>'
3674 . '<button name="export" type="submit" class="'
3675 . 'btn btn-info btn-block" id="exportbtn">'
3676 . _('Export')
3677 . '</button>'
3678 );
3679 $report = self::getClass('ReportMaker');
3680 self::arrayRemove('id', $this->databaseFields);
3681 if ($this->node == 'host') {
3682 self::arrayRemove('pingstatus', $this->databaseFields);
3683 }
3684 Route::listem($this->node);
3685 $Items = json_decode(
3686 Route::getData()
3687 );
3688 $items = $this->node
3689 . 's';
3690 $Items = $Items->$items;
3691 foreach ((array)$Items as &$Item) {
3692 if ($this->node == 'host') {
3693 $macs = implode(
3694 '|',
3695 $Item->macs
3696 );
3697 $report->addCSVCell($macs);
3698 unset($macs);
3699 }
3700 $keys = array_keys((array)$this->databaseFields);
3701 foreach ((array)$keys as $ind => &$field) {
3702 $report->addCSVCell($Item->$field);
3703 unset($field);
3704 }
3705 self::$HookManager->processEvent(
3706 sprintf(
3707 '%s_EXPORT_REPORT',
3708 strtoupper($this->childClass)
3709 ),
3710 array(
3711 'report' => &$report,
3712 $this->childClass => &$Item
3713 )
3714 );
3715 $report->endCSVLine();
3716 unset($Item);
3717 }
3718 $_SESSION['foglastreport'] = serialize($report);
3719 array_walk($fields, $this->fieldsToData);
3720 self::$HookManager->processEvent(
3721 strtoupper($this->node) . '_EXPORT',
3722 array(
3723 'data' => &$this->data,
3724 'headerData' => &$this->headerData,
3725 'templates' => &$this->templates,
3726 'attributes' => &$this->attributes
3727 )
3728 );
3729 echo '<div class="col-xs-9">';
3730 echo '<div class="panel panel-info">';
3731 echo '<div class="panel-heading text-center">';
3732 echo '<h4 class="title">';
3733 echo $this->title;
3734 echo '</h4>';
3735 echo '</div>';
3736 echo '<div class="panel-body">';
3737 echo '<form class="form-horizontal" method="post" action="export.php?type='
3738 . $this->node
3739 . '">';
3740 $this->render(12);
3741 echo '</form>';
3742 echo '</div>';
3743 echo '</div>';
3744 echo '</div>';
3745 }
3746 /**
3747 * Presents the importer elements
3748 *
3749 * @return void
3750 */
3751 public function import()
3752 {
3753 $this->title = _('Import')
3754 . ' '
3755 . $this->childClass
3756 . ' '
3757 . _('List');
3758 unset(
3759 $this->data,
3760 $this->form,
3761 $this->headerData,
3762 $this->templates,
3763 $this->attributes
3764 );
3765 $this->attributes = array(
3766 array('class' => 'col-xs-4'),
3767 array('class' => 'col-xs-8'),
3768 );
3769 $this->templates = array(
3770 '${field}',
3771 '${input}',
3772 );
3773 $this->data[] = array(
3774 'field' => '<label for="import">'
3775 . _('Import CSV')
3776 . '<br/>'
3777 . _('Max Size')
3778 . ': '
3779 . ini_get('post_max_size')
3780 . '</label>',
3781 'input' => '<div class="input-group">'
3782 . '<label class="input-group-btn">'
3783 . '<span class="btn btn-info">'
3784 . _('Browse')
3785 . '<input type="file" class="hidden" name="file" id="import"/>'
3786 . '</span>'
3787 . '</label>'
3788 . '<input type="text" class="form-control filedisp" readonly/>'
3789 . '</div>'
3790 );
3791 $this->data[] = array(
3792 'field' => '<label for="importbtn">'
3793 . _('Import CSV?')
3794 . '</label>',
3795 'input' => '<button type="submit" name="importbtn" class="'
3796 . 'btn btn-info btn-block" id="importbtn">'
3797 . _('Import')
3798 . '</button>'
3799 );
3800 self::$HookManager->processEvent(
3801 'IMPORT_CSV_'
3802 . strtoupper($this->node),
3803 array(
3804 'data' => &$this->data,
3805 'headerData' => &$this->headerData,
3806 'templates' => &$this->templates,
3807 'attributes' => &$this->attributes
3808 )
3809 );
3810 echo '<div class="col-xs-9">';
3811 echo '<div class="panel panel-info">';
3812 echo '<div class="panel-heading text-center">';
3813 echo '<h4 class="title">';
3814 echo $this->title;
3815 echo '</h4>';
3816 echo '</div>';
3817 echo '<div class="panel-body">';
3818 echo '<form class="form-horizontal" method="post" action="'
3819 . $this->formAction
3820 . '" enctype="multipart/form-data">';
3821 echo _('This page allows you to upload a CSV file into FOG to ease')
3822 . ' '
3823 . _('migration or mass import new items')
3824 . '. '
3825 . _('It will operate based on the fields the area typically requires')
3826 . '.';
3827 echo '<hr/>';
3828 $this->render(12);
3829 echo '</form>';
3830 echo '</div>';
3831 echo '</div>';
3832 echo '</div>';
3833 }
3834 /**
3835 * Perform the import based on the uploaded file
3836 *
3837 * @return void
3838 */
3839 public function importPost()
3840 {
3841 try {
3842 $mimes = array(
3843 'text/csv',
3844 'text/anytext',
3845 'text/comma-separated-values',
3846 'application/csv',
3847 'application/excel',
3848 'application/vnd.msexcel',
3849 'application/vnd.ms-excel',
3850 );
3851 $fileinfo = pathinfo($_FILES['file']['name']);
3852 $ext = $fileinfo['extension'];
3853 $Item = new $this->childClass();
3854 $mime = $_FILES['file']['type'];
3855 if (!in_array($mime, $mimes)) {
3856 if ($ext !== 'csv') {
3857 self::setMessage(_('File must be a csv'));
3858 self::redirect($this->formAction);
3859 }
3860 }
3861 if ($_FILES['file']['error'] > 0) {
3862 throw new UploadException($_FILES['file']['error']);
3863 }
3864 $tmpf = pathinfo($_FILES['file']['tmp_name']);
3865 $file = sprintf(
3866 '%s%s%s',
3867 $tmpf['dirname'],
3868 DS,
3869 $tmpf['basename']
3870 );
3871 if (!file_exists($file)) {
3872 throw new Exception(_('Could not find temp filename'));
3873 }
3874 $numSuccess = $numFailed = $numAlreadExist = 0;
3875 $fh = fopen($file, 'rb');
3876 self::arrayRemove(
3877 'id',
3878 $this->databaseFields
3879 );
3880 $comma_count = count(array_keys($this->databaseFields));
3881 $iterator = 0;
3882 if ($Item instanceof Host) {
3883 $comma_count++;
3884 $iterator = 1;
3885 }
3886 $ItemMan = $Item->getManager();
3887 $modules = self::getSubObjectIDs(
3888 'Module',
3889 array('isDefault' => 1)
3890 );
3891 $totalRows = 0;
3892 while (($data = fgetcsv($fh, 1000, ',')) !== false) {
3893 $importCount = count($data);
3894 if ($importCount > 0
3895 && $importCount > $comma_count
3896 ) {
3897 throw new Exception(
3898 _('Invalid data being parsed')
3899 );
3900 }
3901 try {
3902 $dbkeys = array_keys($this->databaseFields);
3903 if ($Item instanceof Host) {
3904 $macs = self::parseMacList($data[0]);
3905 self::$Host = $Item;
3906 self::getClass('HostManager')
3907 ->getHostByMacAddresses($macs);
3908 if (self::$Host->isValid()) {
3909 throw new Exception(
3910 _('One or more macs are associated with a host')
3911 );
3912 }
3913 $primac = array_shift($macs);
3914 $index = array_search('productKey', $dbkeys) + 1;
3915 $test_encryption = self::aesdecrypt($data[$index]);
3916 $test_base64 = base64_decode($data[$index]);
3917 $mb_str = mb_detect_encoding(
3918 $test_base64,
3919 'utf-8',
3920 true
3921 );
3922 $mb_enc = mb_detect_encoding(
3923 $test_encryption,
3924 'utf-8',
3925 true
3926 );
3927 if ($test_base64 && $mb_str) {
3928 $data[$index] = $test_base64;
3929 } elseif ($mb_enc) {
3930 $data[$index] = $test_encryption;
3931 }
3932 }
3933 if ($ItemMan->exists($data[$iterator])) {
3934 throw new Exception(
3935 _('This host already exists')
3936 );
3937 }
3938 foreach ((array)$dbkeys as $ind => &$field) {
3939 $ind += $iterator;
3940 if ($field == 'password') {
3941 $Item->set($field, $data[$ind], true);
3942 } else {
3943 $Item->set($field, $data[$ind]);
3944 }
3945 unset($field);
3946 }
3947 if ($Item instanceof Host) {
3948 $Item
3949 ->set('modules', $modules)
3950 ->addPriMAC($primac)
3951 ->addAddMAC($macs);
3952 }
3953 if ($Item->save()) {
3954 $Item->load();
3955 $totalRows++;
3956 $itemCap = strtoupper($this->childClass);
3957 $event = sprintf(
3958 '%s_IMPORT',
3959 $itemCap
3960 );
3961 $arr = array(
3962 'data' => &$data,
3963 $this->childClass => &$Item
3964 );
3965 self::$HookManager->processEvent(
3966 $event,
3967 $arr
3968 );
3969 $numSuccess++;
3970 $Item = new $this->childClass();
3971 } else {
3972 $numFailed++;
3973 }
3974 } catch (Exception $e) {
3975 $numFailed++;
3976 $uploadErrors .= sprintf(
3977 '%s #%s: %s<br/>',
3978 _('Row'),
3979 $totalRows,
3980 $e->getMessage()
3981 );
3982 }
3983 }
3984 fclose($fh);
3985 } catch (Exception $e) {
3986 $error = $e->getMessage();
3987 }
3988 $this->title = sprintf(
3989 '%s %s %s',
3990 _('Import'),
3991 $this->childClass,
3992 _('Results')
3993 );
3994 unset($this->headerData);
3995 $this->templates = array(
3996 '${field}',
3997 '${input}',
3998 );
3999 $this->attributes = array(
4000 array(),
4001 array(),
4002 );
4003 $fields = array(
4004 _('Total Rows') => $totalRows,
4005 sprintf(
4006 '%s %ss',
4007 _('Successful'),
4008 $this->childClass
4009 ) => $numSuccess,
4010 sprintf(
4011 '%s %ss',
4012 _('Failed'),
4013 $this->childClass
4014 ) => $numFailed,
4015 _('Errors') => $uploadErrors,
4016 );
4017 foreach ((array)$fields as $field => &$input) {
4018 $this->data[] = array(
4019 'field' => $field,
4020 'input' => $input
4021 );
4022 unset($input);
4023 }
4024 $upper = strtoupper($this->childClass);
4025 $event = sprintf(
4026 '%s_IMPORT_FIELDS',
4027 $upper
4028 );
4029 $arr = array(
4030 'headerData' => &$this->headerData,
4031 'data' => &$this->data,
4032 'templates' => &$this->templates,
4033 'attributes' => &$this->attributes
4034 );
4035 self::$HookManager->processEvent(
4036 $event,
4037 $arr
4038 );
4039 $this->render();
4040 }
4041 /**
4042 * Build select form in generic form.
4043 *
4044 * @param string $name The name of the select item.
4045 * @param array $items The items to generate.
4046 * @param string $selected The item to select.
4047 * @param bool $useidsel Use id of array as selector/value.
4048 * @param string $addClass Add additional Classes.
4049 *
4050 * @return string
4051 */
4052 public static function selectForm(
4053 $name,
4054 $items = array(),
4055 $selected = '',
4056 $useidsel = false,
4057 $addClass = ''
4058 ) {
4059 ob_start();
4060 printf(
4061 '<select class="form-control'
4062 . (
4063 $addClass ?
4064 " $addClass" :
4065 ''
4066 )
4067 . '" id="%s" name="%s">'
4068 . '<option value="">- %s -</option>',
4069 $name,
4070 $name,
4071 _('Please select an option')
4072 );
4073 foreach ($items as $id => &$item) {
4074 printf(
4075 '<option value="%s"%s>%s</option>',
4076 (
4077 $useidsel ?
4078 $id :
4079 $item
4080 ),
4081 (
4082 $useidsel ? (
4083 $id == $selected ?
4084 ' selected' :
4085 ''
4086 ) : (
4087 $item == $selected ?
4088 ' selected' :
4089 ''
4090 )
4091 ),
4092 $item
4093 );
4094 unset($item);
4095 }
4096 echo '</select>';
4097 return ob_get_clean();
4098 }
4099 /**
4100 * Displays "add" powermanagement item
4101 *
4102 * @return void
4103 */
4104 public function newPMDisplay()
4105 {
4106 // New data
4107 unset(
4108 $this->headerData,
4109 $this->templates,
4110 $this->attributes,
4111 $this->data
4112 );
4113 $this->templates = array(
4114 '${field}',
4115 '${input}',
4116 );
4117 $this->attributes = array(
4118 array('class' => 'col-xs-4'),
4119 array('class' => 'col-xs-8'),
4120 );
4121 $fields = array(
4122 '<label for="specialCrons">'
4123 . _('Schedule Power')
4124 . '</label>' => '<div class="cronOptions input-group">'
4125 . FOGCron::buildSpecialCron('specialCrons')
4126 . '</div>'
4127 . '<div class="col-xs-12">'
4128 . '<div class="cronInputs">'
4129 . '<div class="col-xs-2">'
4130 . '<div class="input-group">'
4131 . '<input type="text" name="scheduleCronMin" '
4132 . 'placeholder="min" autocomplete="off" '
4133 . 'class="form-control scheduleCronMin cronInput"/>'
4134 . '</div>'
4135 . '</div>'
4136 . '<div class="col-xs-2">'
4137 . '<div class="input-group">'
4138 . '<input type="text" name="scheduleCronHour" '
4139 . 'placeholder="hour" autocomplete="off" '
4140 . 'class="form-control scheduleCronHour cronInput"/>'
4141 . '</div>'
4142 . '</div>'
4143 . '<div class="col-xs-2">'
4144 . '<div class="input-group">'
4145 . '<input type="text" name="scheduleCronDOM" '
4146 . 'placeholder="dom" autocomplete="off" '
4147 . 'class="form-control scheduleCronDOM cronInput"/>'
4148 . '</div>'
4149 . '</div>'
4150 . '<div class="col-xs-2">'
4151 . '<div class="input-group">'
4152 . '<input type="text" name="scheduleCronMonth" '
4153 . 'placeholder="month" autocomplete="off" '
4154 . 'class="form-control scheduleCronMonth cronInput"/>'
4155 . '</div>'
4156 . '</div>'
4157 . '<div class="col-xs-2">'
4158 . '<div class="input-group">'
4159 . '<input type="text" name="scheduleCronDOW" '
4160 . 'placeholder="dow" autocomplete="off" '
4161 . 'class="form-control scheduleCronDOW cronInput"/>'
4162 . '</div>'
4163 . '</div>'
4164 . '</div>'
4165 . '</div>',
4166 '<label for="scheduleOnDemand">'
4167 . _('Perform Immediately?')
4168 . '</label>' => '<input type="checkbox" name="onDemand" id='
4169 . '"scheduleOnDemand"'
4170 . (
4171 isset($_POST['onDemand']) ?
4172 ' checked' :
4173 ''
4174 )
4175 . '/>',
4176 '<label for="action">'
4177 . _('Action')
4178 . '</label>' => self::getClass(
4179 'PowerManagementManager'
4180 )->getActionSelect(
4181 filter_input(INPUT_POST, 'action'),
4182 false,
4183 'action'
4184 ),
4185 '<label for="pmsubmit">'
4186 . _('Create new PM Schedule')
4187 . '</label>' => '<button type="submit" name="pmsubmit" id='
4188 . '"pmsubmit" class="btn btn-info btn-block">'
4189 . _('Add')
4190 . '</button>'
4191 );
4192 array_walk($fields, $this->fieldsToData);
4193 echo '<div class="panel panel-info">';
4194 echo '<div class="panel-heading text-center">';
4195 echo '<h4 class="title">';
4196 echo _('New power management task');
4197 echo '</h4>';
4198 echo '</div>';
4199 echo '<div class="panel-body">';
4200 echo '<form class="deploy-container form-horizontal" '
4201 . 'method="post" action="'
4202 . $this->formAction
4203 . '&tab='
4204 . $this->node
4205 . '-powermanagement">';
4206 $this->render(12);
4207 echo '</form>';
4208 echo '</div>';
4209 echo '</div>';
4210 }
4211 /**
4212 * Index page is already common, but other pages
4213 * might want to do similar after minor changes. This allows
4214 * it to happen.
4215 *
4216 * @param bool $delNeeded If we need to be able to delete items.
4217 * @param bool|string $storage If storage, set node or group.
4218 * @param bool $actionbox If we need to label as action box.
4219 *
4220 * @return void
4221 */
4222 public function indexDivDisplay(
4223 $delNeeded = false,
4224 $storage = false,
4225 $actionbox = false
4226 ) {
4227 ob_start();
4228 echo '<div class="panel panel-info">';
4229 echo '<div class="panel-heading text-center">';
4230 echo '<h4 class="title">';
4231 echo $this->title;
4232 echo '</h4>';
4233 echo '</div>';
4234 echo '<div class="panel-body">';
4235 echo $this->render(12);
4236 echo '</div>';
4237 echo '</div>';
4238 if (!$delNeeded) {
4239 $items = ob_get_clean();
4240 self::$HookManager->processEvent(
4241 'INDEX_DIV_DISPLAY_CHANGE',
4242 array(
4243 'items' => &$items,
4244 'childClass' => &$this->childClass,
4245 'main' => &$this,
4246 'delNeeded' => &$delNeeded
4247 )
4248 );
4249 echo $items;
4250 return;
4251 }
4252 if ($actionbox) {
4253 echo '<div class="action-boxes del hiddeninitially">';
4254 }
4255 echo '<div class="panel panel-warning">';
4256 echo '<div class="panel-heading text-center">';
4257 echo '<h4 class="title">';
4258 echo _('Delete Selected');
4259 echo '</h4>';
4260 echo '</div>';
4261 echo '<div class="panel-body">';
4262 $formAction = $this->formAction;
4263 $components = parse_url($formAction);
4264 parse_str($components['query'], $vars);
4265 $vars['sub'] = 'deletemulti';
4266 $formAction = '?'.http_build_query($vars);
4267 echo '<form class="form-horizontal" method="post" action="'
4268 . $formAction
4269 . '">';
4270 echo '<div class="form-group">';
4271 echo '<label class="control-label col-xs-4" for="del-'
4272 . $this->node
4273 . '">';
4274 echo _('Delete selected');
4275 echo ' ';
4276 echo(
4277 $storage ?
4278 $this->node . ' ' . $storage :
4279 $this->node
4280 );
4281 echo 's';
4282 echo '</label>';
4283 echo '<div class="col-xs-8">';
4284 echo '<input type="hidden" name="'
4285 . $this->node
4286 . 'IDArray"/>';
4287 echo '<button type="submit" class='
4288 . '"btn btn-danger btn-block" id="'
4289 . 'del-'
4290 . $this->node
4291 . '">';
4292 echo _('Delete');
4293 echo '</button>';
4294 echo '</div>';
4295 echo '</div>';
4296 echo '</form>';
4297 echo '</div>';
4298 echo '</div>';
4299 if ($actionbox) {
4300 echo '</div>';
4301 }
4302 $items = ob_get_clean();
4303 self::$HookManager->processEvent(
4304 'INDEX_DIV_DISPLAY_CHANGE',
4305 array(
4306 'items' => &$items,
4307 'childClass' => &$this->childClass,
4308 'main' => &$this,
4309 'delNeeded' => &$delNeeded
4310 )
4311 );
4312 echo $items;
4313 }
4314 }