"Fossies" - the Fresh Open Source Software Archive

Member "fogproject-1.5.9/packages/web/lib/fog/host.class.php" (13 Sep 2020, 66290 Bytes) of package /linux/misc/fogproject-1.5.9.tar.gz:


As a special service "Fossies" has tried to format the requested source page into HTML format using (guessed) PHP 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 "host.class.php": 1.5.8_vs_1.5.9.

    1 <?php
    2 /**
    3  * The host object (main item FOG deals with
    4  *
    5  * PHP version 5
    6  *
    7  * @category Host
    8  * @package  FOGProject
    9  * @author   Tom Elliott <tommygunsster@gmail.com>
   10  * @license  http://opensource.org/licenses/gpl-3.0.txt GPLv3
   11  * @link     https://fogproject.org
   12  */
   13 /**
   14  * The host object (main item FOG deals with
   15  *
   16  * @category Host
   17  * @package  FOGProject
   18  * @author   Tom Elliott <tommygunsster@gmail.com>
   19  * @license  http://opensource.org/licenses/gpl-3.0.txt GPLv3
   20  * @link     https://fogproject.org
   21  */
   22 class Host extends FOGController
   23 {
   24     /**
   25      * The host table
   26      *
   27      * @var string
   28      */
   29     protected $databaseTable = 'hosts';
   30     /**
   31      * The Host table fields and common names
   32      *
   33      * @var array
   34      */
   35     protected $databaseFields = array(
   36         'id' => 'hostID',
   37         'name' => 'hostName',
   38         'description' => 'hostDesc',
   39         'ip' => 'hostIP',
   40         'imageID' => 'hostImage',
   41         'building' => 'hostBuilding',
   42         'createdTime' => 'hostCreateDate',
   43         'deployed' => 'hostLastDeploy',
   44         'createdBy' => 'hostCreateBy',
   45         'useAD' => 'hostUseAD',
   46         'ADDomain' => 'hostADDomain',
   47         'ADOU' => 'hostADOU',
   48         'ADUser' => 'hostADUser',
   49         'ADPass' => 'hostADPass',
   50         'ADPassLegacy' => 'hostADPassLegacy',
   51         'productKey' => 'hostProductKey',
   52         'printerLevel' => 'hostPrinterLevel',
   53         'kernelArgs' => 'hostKernelArgs',
   54         'kernel' => 'hostKernel',
   55         'kernelDevice' => 'hostDevice',
   56         'init' => 'hostInit',
   57         'pending' => 'hostPending',
   58         'pub_key' => 'hostPubKey',
   59         'sec_tok' => 'hostSecToken',
   60         'sec_time' => 'hostSecTime',
   61         'pingstatus' => 'hostPingCode',
   62         'biosexit' => 'hostExitBios',
   63         'efiexit' => 'hostExitEfi',
   64         'enforce' => 'hostEnforce'
   65     );
   66     /**
   67      * The required fields
   68      *
   69      * @var array
   70      */
   71     protected $databaseFieldsRequired = array(
   72         'name'
   73     );
   74     /**
   75      * Additional fields
   76      *
   77      * @var array
   78      */
   79     protected $additionalFields = array(
   80         'mac',
   81         'primac',
   82         'imagename',
   83         'additionalMACs',
   84         'pendingMACs',
   85         'groups',
   86         'groupsnotinme',
   87         'hostscreen',
   88         'hostalo',
   89         'optimalStorageNode',
   90         'printers',
   91         'printersnotinme',
   92         'snapins',
   93         'snapinsnotinme',
   94         'modules',
   95         'inventory',
   96         'task',
   97         'snapinjob',
   98         'users',
   99         'fingerprint',
  100         'powermanagementtasks'
  101     );
  102     /**
  103      * Database -> Class field relationships
  104      *
  105      * @var array
  106      */
  107     protected $databaseFieldClassRelationships = array(
  108         'MACAddressAssociation' => array(
  109             'hostID',
  110             'id',
  111             'primac',
  112             array('primary' => 1)
  113         ),
  114         'Image' => array(
  115             'id',
  116             'imageID',
  117             'imagename'
  118         ),
  119         'HostScreenSetting' => array(
  120             'hostID',
  121             'id',
  122             'hostscreen'
  123         ),
  124         'HostAutoLogout' => array(
  125             'hostID',
  126             'id',
  127             'hostalo'
  128         ),
  129         'Inventory' => array(
  130             'hostID',
  131             'id',
  132             'inventory'
  133         )
  134     );
  135     /**
  136      * Display val storage
  137      *
  138      * @var array
  139      */
  140     private static $_hostscreen = array();
  141     /**
  142      * ALO time val
  143      *
  144      * @var int
  145      */
  146     private static $_hostalo = array();
  147     /**
  148      * Set value to key
  149      *
  150      * @param string $key   the key to set to
  151      * @param mixed  $value the value to set
  152      *
  153      * @throws Exception
  154      * @return object
  155      */
  156     public function set($key, $value)
  157     {
  158         $key = $this->key($key);
  159         switch ($key) {
  160         case 'mac':
  161             if (!($value instanceof MACAddress)) {
  162                 $value = new MACAddress($value);
  163                 $value = $value->__toString();
  164             }
  165             break;
  166         case 'additionalMACs':
  167         case 'pendingMACs':
  168             $newValue = array_map(
  169                 function (&$mac) {
  170                     return new MACAddress($mac);
  171                 },
  172                 (array)$value
  173             );
  174             $value = (array)$newValue;
  175             break;
  176         case 'snapinjob':
  177             if (!($value instanceof SnapinJob)) {
  178                 $value = new SnapinJob($value);
  179             }
  180             break;
  181         case 'task':
  182             if (!($value instanceof Task)) {
  183                 $value = new Task($value);
  184             }
  185             break;
  186         }
  187         return parent::set($key, $value);
  188     }
  189     /**
  190      * Add value to key (array)
  191      *
  192      * @param string $key   the key to add to
  193      * @param mixed  $value the value to add
  194      *
  195      * @throws Exception
  196      * @return object
  197      */
  198     public function add($key, $value)
  199     {
  200         $key = $this->key($key);
  201         switch ($key) {
  202         case 'additionalMACs':
  203         case 'pendingMACs':
  204             if (!($value instanceof MACAddress)) {
  205                 $value = new MACAddress($value);
  206             }
  207             break;
  208         }
  209         return parent::add($key, $value);
  210     }
  211     /**
  212      * Removes the item from the database
  213      *
  214      * @param string $key the key to remove
  215      *
  216      * @throws Exception
  217      * @return object
  218      */
  219     public function destroy($key = 'id')
  220     {
  221         $find = array('hostID' => $this->get('id'));
  222         self::getClass('NodeFailureManager')
  223             ->destroy($find);
  224         self::getClass('ImagingLogManager')
  225             ->destroy($find);
  226         self::getClass('SnapinTaskManager')
  227             ->destroy(
  228                 array(
  229                     'jobID' => self::getSubObjectIDs(
  230                         'SnapinJob',
  231                         $find,
  232                         'id'
  233                     )
  234                 )
  235             );
  236         self::getClass('SnapinJobManager')
  237             ->destroy($find);
  238         self::getClass('TaskManager')
  239             ->destroy($find);
  240         self::getClass('ScheduledTaskManager')
  241             ->destroy($find);
  242         self::getClass('HostAutoLogoutManager')
  243             ->destroy($find);
  244         self::getClass('HostScreenSettingManager')
  245             ->destroy($find);
  246         self::getClass('GroupAssociationManager')
  247             ->destroy($find);
  248         self::getClass('SnapinAssociationManager')
  249             ->destroy($find);
  250         self::getClass('PrinterAssociationManager')
  251             ->destroy($find);
  252         self::getClass('ModuleAssociationManager')
  253             ->destroy($find);
  254         self::getClass('GreenFogManager')
  255             ->destroy($find);
  256         self::getClass('InventoryManager')
  257             ->destroy($find);
  258         self::getClass('UserTrackingManager')
  259             ->destroy($find);
  260         self::getClass('MACAddressAssociationManager')
  261             ->destroy($find);
  262         self::getClass('PowerManagementManager')
  263             ->destroy($find);
  264         self::$HookManager
  265             ->processEvent(
  266                 'DESTROY_HOST',
  267                 array(
  268                     'Host' => &$this
  269                 )
  270             );
  271         return parent::destroy($key);
  272     }
  273     /**
  274      * Returns Valid MACs
  275      *
  276      * @param array $macs the array of macs
  277      * @param array $arr  the array to define
  278      *
  279      * @return array
  280      */
  281     private static function _retValidMacs($macs, &$arr)
  282     {
  283         $addMacs = array();
  284         foreach ((array)$macs as &$mac) {
  285             if (!($mac instanceof MACAddress)) {
  286                 $mac = new MACAddress($mac);
  287             }
  288             if (!$mac->isValid()) {
  289                 continue;
  290             }
  291             $addMacs[] = $mac->__toString();
  292             unset($mac);
  293         }
  294         return $arr = $addMacs;
  295     }
  296     /**
  297      * Stores data into the database
  298      *
  299      * @return bool|object
  300      */
  301     public function save()
  302     {
  303         parent::save();
  304         if ($this->isLoaded('mac')) {
  305             if (!$this->get('mac')->isValid()) {
  306                 throw new Exception(self::$foglang['InvalidMAC']);
  307             }
  308             $RealPriMAC = $this->get('mac')->__toString();
  309             $CurrPriMAC = self::getSubObjectIDs(
  310                 'MACAddressAssociation',
  311                 array(
  312                     'hostID' => $this->get('id'),
  313                     'primary' => 1
  314                 ),
  315                 'mac'
  316             );
  317             if (count($CurrPriMAC) === 1
  318                 && $CurrPriMAC[0] != $RealPriMAC
  319             ) {
  320                 self::getClass('MACAddressAssociationManager')
  321                     ->destroy(
  322                         array(
  323                             'hostID' => $this->get('id'),
  324                             'mac' => $CurrPriMAC[0]
  325                         )
  326                     );
  327             }
  328             $HostWithMAC = array_diff(
  329                 (array)$this->get('id'),
  330                 (array)self::getSubObjectIDs(
  331                     'MACAddressAssociation',
  332                     array('mac' => $RealPriMAC),
  333                     'hostID'
  334                 )
  335             );
  336             if (count($HostWithMAC)
  337                 && !in_array($this->get('id'), (array)$HostWithMAC)
  338             ) {
  339                 throw new Exception(_('This MAC Belongs to another host'));
  340             }
  341             $DBPriMACs = self::getSubObjectIDs(
  342                 'MACAddressAssociation',
  343                 array(
  344                     'hostID' => $this->get('id'),
  345                     'primary' => 1
  346                 ),
  347                 'mac'
  348             );
  349             $RemoveMAC = array_diff(
  350                 (array)$RealPriMAC,
  351                 (array)$DBPriMACs
  352             );
  353             if (count($RemoveMAC)) {
  354                 self::getClass('MACAddressAssociationManager')
  355                     ->destroy(
  356                         array('mac' => $RemoveMAC)
  357                     );
  358                 unset($RemoveMAC);
  359                 $DBPriMACs = self::getSubObjectIDs(
  360                     'MACAddressAssociation',
  361                     array(
  362                         'hostID' => $this->get('id'),
  363                         'primary' => 1
  364                     ),
  365                     'mac'
  366                 );
  367             }
  368             if (!in_array($RealPriMAC, $DBPriMACs)) {
  369                 self::getClass('MACAddressAssociation')
  370                     ->set('hostID', $this->get('id'))
  371                     ->set('mac', $RealPriMAC)
  372                     ->set('primary', 1)
  373                     ->save();
  374             }
  375             unset(
  376                 $DBPriMACs,
  377                 $RealPriMAC,
  378                 $RemoveMAC,
  379                 $HostWithMAC
  380             );
  381         }
  382         if ($this->isLoaded('additionalMACs')) {
  383             self::_retValidMacs(
  384                 $this->get('additionalMACs'),
  385                 $addMacs
  386             );
  387             $RealAddMACs = array_filter($addMacs);
  388             unset($addMacs);
  389             $RealAddMACs = array_unique($RealAddMACs);
  390             $RealAddMACs = array_filter($RealAddMACs);
  391             $DBPriMACs = self::getSubObjectIDs(
  392                 'MACAddressAssociation',
  393                 array('primary' => 1),
  394                 'mac'
  395             );
  396             foreach ((array)$DBPriMACs as &$mac) {
  397                 if (self::arrayStrpos($mac, $RealAddMACs) !== false) {
  398                     throw new Exception(
  399                         _('Cannot add Primary mac as additional mac')
  400                     );
  401                 }
  402                 unset($mac);
  403             }
  404             unset($DBPriMACs);
  405             $PreOwnedMACs = self::getSubObjectIDs(
  406                 'MACAddressAssociation',
  407                 array(
  408                     'hostID' => $this->get('id'),
  409                     'pending' => 1
  410                 ),
  411                 'mac',
  412                 true
  413             );
  414             $RealAddMACs = array_diff(
  415                 (array)$RealAddMACs,
  416                 (array)$PreOwnedMACs
  417             );
  418             unset($PreOwnedMACs);
  419             $DBAddMACs = self::getSubObjectIDs(
  420                 'MACAddressAssociation',
  421                 array(
  422                     'hostID' => $this->get('id'),
  423                     'primary' => 0,
  424                     'pending' => 0
  425                 ),
  426                 'mac'
  427             );
  428             $RemoveAddMAC = array_diff(
  429                 (array)$DBAddMACs,
  430                 (array)$RealAddMACs
  431             );
  432             if (count($RemoveAddMAC)) {
  433                 self::getClass('MACAddressAssociationManager')
  434                     ->destroy(
  435                         array(
  436                             'hostID' => $this->get('id'),
  437                             'mac' => $RemoveAddMAC
  438                         )
  439                     );
  440                 $DBAddMACs = self::getSubObjectIDs(
  441                     'MACAddressAssociation',
  442                     array(
  443                         'hostID' => $this->get('id'),
  444                         'primary' => 0,
  445                         'pending' => 0,
  446                         'mac'
  447                     )
  448                 );
  449                 unset($RemoveAddMAC);
  450             }
  451             $insert_fields = array(
  452                 'hostID',
  453                 'mac',
  454                 'primary',
  455                 'pending'
  456             );
  457             $insert_values = array();
  458             $RealAddMACs = array_diff(
  459                 (array)$RealAddMACs,
  460                 (array)$DBAddMACs
  461             );
  462             foreach ((array)$RealAddMACs as $index => &$mac) {
  463                 $insert_values[] = array(
  464                     $this->get('id'),
  465                     $mac,
  466                     0,
  467                     0
  468                 );
  469                 unset($mac);
  470             }
  471             if (count($insert_values) > 0) {
  472                 self::getClass('MACAddressAssociationManager')
  473                     ->insertBatch(
  474                         $insert_fields,
  475                         $insert_values
  476                     );
  477             }
  478             unset(
  479                 $DBAddMACs,
  480                 $RealAddMACs,
  481                 $RemoveAddMAC
  482             );
  483         }
  484         if ($this->isLoaded('pendingMACs')) {
  485             self::_retValidMacs($this->get('pendingMACs'), $pendMacs);
  486             $RealPendMACs = array_filter($pendMacs);
  487             unset($pendMacs);
  488             $RealPendMACs = array_unique($RealPendMACs);
  489             $RealPendMACs = array_filter($RealPendMACs);
  490             $DBPriMACs = self::getSubObjectIDs(
  491                 'MACAddressAssociation',
  492                 array('primary' => 1),
  493                 'mac'
  494             );
  495             foreach ((array)$DBPriMACs as &$mac) {
  496                 if (self::arrayStrpos($mac, $RealPendMACs)) {
  497                     throw new Exception(
  498                         _('Cannot add a pre-existing primary mac')
  499                     );
  500                 }
  501                 unset($mac);
  502             }
  503             unset($DBPriMACs);
  504             $PreOwnedMACs = self::getSubObjectIDs(
  505                 'MACAddressAssociation',
  506                 array(
  507                     'hostID' => $this->get('id'),
  508                     'pending' => 0,
  509                     'mac',
  510                     true
  511                 ),
  512                 'mac',
  513                 true
  514             );
  515             $RealPendMACs = array_diff(
  516                 (array)$RealPendMACs,
  517                 (array)$PreOwnedMACs
  518             );
  519             unset($PreOwnedMACs);
  520             $DBPendMACs = self::getSubObjectIDs(
  521                 'MACAddressAssociation',
  522                 array(
  523                     'hostID' => $this->get('id'),
  524                     'primary' => 0,
  525                     'pending' => 1,
  526                 ),
  527                 'mac'
  528             );
  529             $RemovePendMAC = array_diff(
  530                 (array)$DBPendMACs,
  531                 (array)$RealPendMACs
  532             );
  533             if (count($RemovePendMAC)) {
  534                 self::getClass('MACAddressAssociationManager')
  535                     ->destroy(
  536                         array(
  537                             'hostID' => $this->get('id'),
  538                             'mac' => $RemovePendMAC
  539                         )
  540                     );
  541                 $DBPendMACs = self::getSubObjectIDs(
  542                     'MACAddressAssociation',
  543                     array(
  544                         'primary' => 0,
  545                         'pending' => 1,
  546                     ),
  547                     'mac'
  548                 );
  549                 unset($RemovePendMAC);
  550             }
  551             $insert_fields = array(
  552                 'hostID',
  553                 'mac',
  554                 'primary',
  555                 'pending'
  556             );
  557             $insert_values = array();
  558             $RealPendMACs = array_diff(
  559                 (array)$RealPendMACs,
  560                 (array)$DBPendMACs
  561             );
  562             foreach ((array)$RealPendMACs as &$mac) {
  563                 $insert_values[] = array(
  564                     $this->get('id'),
  565                     $mac,
  566                     0,
  567                     1
  568                 );
  569                 unset($mac);
  570             }
  571             if (count($insert_values) > 0) {
  572                 self::getClass('MACAddressAssociationManager')
  573                     ->insertBatch(
  574                         $insert_fields,
  575                         $insert_values
  576                     );
  577             }
  578             unset(
  579                 $DBPendMACs,
  580                 $RealPendMACs,
  581                 $RemovePendMAC
  582             );
  583         }
  584         if ($this->isLoaded('powermanagementtasks')) {
  585             $DBPowerManagementIDs = self::getSubObjectIDs(
  586                 'PowerManagement',
  587                 array('hostID'=>$this->get('id'))
  588             );
  589             $RemovePowerManagementIDs = array_diff(
  590                 (array)$DBPowerManagementIDs,
  591                 (array)$this->get('powermanagementtasks')
  592             );
  593             if (count($RemovePowerManagementIDs)) {
  594                 self::getClass('PowerManagementManager')
  595                     ->destroy(
  596                         array(
  597                             'hostID' => $this->get('id'),
  598                             'id' => $RemovePowerManagementIDs
  599                         )
  600                     );
  601                 $DBPowerManagementIDs = self::getSubObjectIDs(
  602                     'PowerManagement',
  603                     array('hostID' => $this->get('id'))
  604                 );
  605                 unset($RemovePowerManagementIDs);
  606             }
  607             $objNeeded = false;
  608             unset($DBPowerManagementIDs, $RemovePowerManagementIDs);
  609         }
  610         return $this
  611             ->assocSetter('Module')
  612             ->assocSetter('Printer')
  613             ->assocSetter('Snapin')
  614             ->assocSetter('Group')
  615             ->load();
  616     }
  617     /**
  618      * Defines if the host is valid
  619      *
  620      * @return bool
  621      */
  622     public function isValid()
  623     {
  624         return parent::isValid() && $this->isHostnameSafe();
  625     }
  626     /**
  627      * Tells us if the hostname is safe to use
  628      *
  629      * @param string $hostname the hostname to test
  630      *
  631      * @return bool
  632      */
  633     public function isHostnameSafe($hostname = '')
  634     {
  635         if (empty($hostname)) {
  636             $hostname = $this->get('name');
  637         }
  638         $pattern = '/^[\\w!@#$%^()\\-\'{}\\.~]{1,15}$/';
  639         return (bool)preg_match($pattern, $hostname);
  640     }
  641     /**
  642      * Returns if the printer is the default
  643      *
  644      * @param int $printerid the printer id to test
  645      *
  646      * @return bool
  647      */
  648     public function getDefault($printerid)
  649     {
  650         return (bool)self::getClass('PrinterAssociationManager')
  651             ->count(
  652                 array(
  653                     'hostID' => $this->get('id'),
  654                     'printerID' => $printerid,
  655                     'isDefault' => 1
  656                 )
  657             );
  658     }
  659     /**
  660      * Updates the default printer
  661      *
  662      * @param int   $printerid the printer id to update
  663      * @param mixed $onoff     whether to enable or disable
  664      *
  665      * @return object
  666      */
  667     public function updateDefault($printerid, $onoff)
  668     {
  669         self::getClass('PrinterAssociationManager')
  670             ->update(
  671                 array(
  672                     'printerID' => $this->get('printers'),
  673                     'hostID' => $this->get('id')
  674                 ),
  675                 '',
  676                 array('isDefault' => 0)
  677             );
  678         self::getClass('PrinterAssociationManager')
  679             ->update(
  680                 array(
  681                     'printerID' => $printerid,
  682                     'hostID' => $this->get('id')
  683                 ),
  684                 '',
  685                 array('isDefault' => $onoff)
  686             );
  687         return $this;
  688     }
  689     /**
  690      * Sets display vals for the host
  691      *
  692      * @return void
  693      */
  694     private function _setDispVals()
  695     {
  696         if (count(self::$_hostscreen)) {
  697             return;
  698         }
  699         if (!$this->get('hostscreen')->isValid()) {
  700             list(
  701                 $refresh,
  702                 $width,
  703                 $height
  704             ) = self::getSubObjectIDs(
  705                 'Service',
  706                 array(
  707                     'name' => array(
  708                         'FOG_CLIENT_DISPLAYMANAGER_R',
  709                         'FOG_CLIENT_DISPLAYMANAGER_X',
  710                         'FOG_CLIENT_DISPLAYMANAGER_Y'
  711                     )
  712                 ),
  713                 'value',
  714                 false,
  715                 'AND',
  716                 'name',
  717                 false,
  718                 false
  719             );
  720         } else {
  721             $refresh = $this->get('hostscreen')->get('refresh');
  722             $width = $this->get('hostscreen')->get('width');
  723             $height = $this->get('hostscreen')->get('height');
  724         }
  725         self::$_hostscreen = array(
  726             'refresh' => $refresh,
  727             'width' => $width,
  728             'height' => $height
  729         );
  730     }
  731     /**
  732      * Gets the display values
  733      *
  734      * @param string $key the key to get
  735      *
  736      * @return mixed
  737      */
  738     public function getDispVals($key = '')
  739     {
  740         $this->_setDispVals();
  741         return self::$_hostscreen[$key];
  742     }
  743     /**
  744      * Sets the display values
  745      *
  746      * @param mixed $x the width
  747      * @param mixed $y the height
  748      * @param mixed $r the refresh
  749      *
  750      * @return object
  751      */
  752     public function setDisp($x, $y, $r)
  753     {
  754         if (!$this->get('hostscreen')->isValid()) {
  755             $this->get('hostscreen')
  756                 ->set('hostID', $this->get('id'));
  757         }
  758         $this->get('hostscreen')
  759             ->set('width', $x)
  760             ->set('height', $y)
  761             ->set('refresh', $r)
  762             ->save();
  763         return $this;
  764     }
  765     /**
  766      * Sets this hosts alo time (or default to global if needed
  767      *
  768      * @return void
  769      */
  770     private function _setAlo()
  771     {
  772         if (!empty(self::$_hostalo)) {
  773             return;
  774         }
  775         if (!$this->get('hostalo')->isValid()) {
  776             self::$_hostalo = self::getSetting('FOG_CLIENT_AUTOLOGOFF_MIN');
  777         } else {
  778             self::$_hostalo = $this->get('hostalo')->get('time');
  779         }
  780         return;
  781     }
  782     /**
  783      * Gets the auto logout time
  784      *
  785      * @return int
  786      */
  787     public function getAlo()
  788     {
  789         $this->_setAlo();
  790         return self::$_hostalo;
  791     }
  792     /**
  793      * Sets the auto logout time
  794      *
  795      * @param int $time the time to set
  796      *
  797      * @return object
  798      */
  799     public function setAlo($time)
  800     {
  801         return $this->get('hostalo')
  802             ->set('hostID', $this->get('id'))
  803             ->set('time', $time)
  804             ->save();
  805     }
  806     /**
  807      * Loads the mac additional field
  808      *
  809      * @return void
  810      */
  811     protected function loadMac()
  812     {
  813         $mac = new MACAddress($this->get('primac'));
  814         $this->set('mac', $mac);
  815     }
  816     /**
  817      * Loads any additional macs
  818      *
  819      * @return void
  820      */
  821     protected function loadAdditionalMACs()
  822     {
  823         $macs = self::getSubObjectIDs(
  824             'MACAddressAssociation',
  825             array(
  826                 'hostID' => $this->get('id'),
  827                 'primary' => 0,
  828                 'pending' => 0,
  829             ),
  830             'mac'
  831         );
  832         $this->set('additionalMACs', (array)$macs);
  833     }
  834     /**
  835      * Loads any pending macs
  836      *
  837      * @return void
  838      */
  839     protected function loadPendingMACs()
  840     {
  841         $macs = self::getSubObjectIDs(
  842             'MACAddressAssociation',
  843             array(
  844                 'hostID' => $this->get('id'),
  845                 'primary' => 0,
  846                 'pending' => 1,
  847             ),
  848             'mac'
  849         );
  850         $this->set('pendingMACs', (array)$macs);
  851     }
  852     /**
  853      * Loads any groups this host is in
  854      *
  855      * @return void
  856      */
  857     protected function loadGroups()
  858     {
  859         $groups = self::getSubObjectIDs(
  860             'GroupAssociation',
  861             array('hostID' => $this->get('id')),
  862             'groupID'
  863         );
  864         $groups = self::getSubObjectIDs(
  865             'Group',
  866             array('id' => $groups)
  867         );
  868         $this->set('groups', (array)$groups);
  869     }
  870     /**
  871      * Loads any groups this host is not in
  872      *
  873      * @return void
  874      */
  875     protected function loadGroupsnotinme()
  876     {
  877         $groups = array_diff(
  878             self::getSubObjectIDs('Group'),
  879             $this->get('groups')
  880         );
  881         $this->set('groupsnotinme', (array)$groups);
  882     }
  883     /**
  884      * Loads any printers those host has
  885      *
  886      * @return void
  887      */
  888     protected function loadPrinters()
  889     {
  890         $printers = self::getSubObjectIDs(
  891             'PrinterAssociation',
  892             array('hostID' => $this->get('id')),
  893             'printerID'
  894         );
  895         $printers = self::getSubObjectIDs(
  896             'Printer',
  897             array('id' => $printers)
  898         );
  899         $this->set('printers', (array)$printers);
  900     }
  901     /**
  902      * Loads any printers this host does not have
  903      *
  904      * @return void
  905      */
  906     protected function loadPrintersnotinme()
  907     {
  908         $printers = array_diff(
  909             self::getSubObjectIDs('Printer'),
  910             $this->get('printers')
  911         );
  912         $this->set('printersnotinme', (array)$printers);
  913     }
  914     /**
  915      * Loads any snapins this host has
  916      *
  917      * @return void
  918      */
  919     protected function loadSnapins()
  920     {
  921         $snapins = self::getSubObjectIDs(
  922             'SnapinAssociation',
  923             array('hostID' => $this->get('id')),
  924             'snapinID'
  925         );
  926         $snapins = self::getSubObjectIDs(
  927             'Snapin',
  928             array('id' => $snapins)
  929         );
  930         $this->set('snapins', (array)$snapins);
  931     }
  932     /**
  933      * Loads any snapins this host does not have
  934      *
  935      * @return void
  936      */
  937     protected function loadSnapinsnotinme()
  938     {
  939         $snapins = array_diff(
  940             self::getSubObjectIDs('Snapin'),
  941             $this->get('snapins')
  942         );
  943         $this->set('snapinsnotinme', (array)$snapins);
  944     }
  945     /**
  946      * Loads any modules this host has
  947      *
  948      * @return void
  949      */
  950     protected function loadModules()
  951     {
  952         $modules = self::getSubObjectIDs(
  953             'ModuleAssociation',
  954             array('hostID' => $this->get('id')),
  955             'moduleID'
  956         );
  957         $modules = self::getSubObjectIDs(
  958             'Module',
  959             array('id' => $modules)
  960         );
  961         $this->set('modules', (array)$modules);
  962     }
  963     /**
  964      * Loads any powermanagement tasks this host has
  965      *
  966      * @return void
  967      */
  968     protected function loadPowermanagementtasks()
  969     {
  970         $pms = self::getSubObjectIDs(
  971             'PowerManagement',
  972             array('hostID' => $this->get('id'))
  973         );
  974         $this->set('powermanagementtasks', (array)$pms);
  975     }
  976     /**
  977      * Loads any users have logged in
  978      *
  979      * @return void
  980      */
  981     protected function loadUsers()
  982     {
  983         $users = self::getSubObjectIDs(
  984             'UserTracking',
  985             array('hostID' => $this->get('id'))
  986         );
  987         $this->set('users', (array)$users);
  988     }
  989     /**
  990      * Loads the current snapin job
  991      *
  992      * @return void
  993      */
  994     protected function loadSnapinjob()
  995     {
  996         $sjID = self::getSubObjectIDs(
  997             'SnapinJob',
  998             array(
  999                 'stateID' => self::fastmerge(
 1000                     self::getQueuedStates(),
 1001                     (array)self::getProgressState()
 1002                 ),
 1003                 'hostID' => $this->get('id')
 1004             )
 1005         );
 1006         $SnapinJob = new SnapinJob(@min($sjID));
 1007         $this->set('snapinjob', $SnapinJob);
 1008     }
 1009     /**
 1010      * Loads the current task
 1011      *
 1012      * @return void
 1013      */
 1014     protected function loadTask()
 1015     {
 1016         $find['hostID'] = $this->get('id');
 1017         $find['stateID'] = self::fastmerge(
 1018             self::getQueuedStates(),
 1019             (array)self::getProgressState()
 1020         );
 1021         $types = array(
 1022             'up',
 1023             'down'
 1024         );
 1025         $type = filter_input(INPUT_POST, 'type');
 1026         if (!$type) {
 1027             $type = filter_input(INPUT_GET, 'type');
 1028         }
 1029         $type = trim($type);
 1030         if (in_array($type, $types)) {
 1031             if ($type === 'up') {
 1032                 $find['typeID'] = array(2, 16);
 1033             } else {
 1034                 $find['typeID'] = array(
 1035                     1,
 1036                     8,
 1037                     15,
 1038                     17,
 1039                     24
 1040                 );
 1041             }
 1042         }
 1043         $taskID = self::getSubObjectIDs(
 1044             'Task',
 1045             $find
 1046         );
 1047         $taskID = array_shift($taskID);
 1048         $this->set('task', $taskID);
 1049         unset($find);
 1050     }
 1051     /**
 1052      * Loads the optimal storage node
 1053      *
 1054      * @return void
 1055      */
 1056     protected function loadOptimalStorageNode()
 1057     {
 1058         $node = $this
 1059             ->getImage()
 1060             ->getStorageGroup()
 1061             ->getOptimalStorageNode();
 1062         $this->set('optimalStorageNode', $node);
 1063     }
 1064     /**
 1065      * Gets the active task count
 1066      *
 1067      * @return int
 1068      */
 1069     public function getActiveTaskCount()
 1070     {
 1071         $find = array(
 1072             'stateID' => self::fastmerge(
 1073                 self::getQueuedStates(),
 1074                 (array)self::getProgressState()
 1075             ),
 1076             'hostID' => $this->get('id')
 1077         );
 1078         $count = self::getClass('TaskManager')
 1079             ->count($find);
 1080         return (int)$count;
 1081     }
 1082     /**
 1083      * Returns the optimal storage node
 1084      *
 1085      * @return object
 1086      */
 1087     public function getOptimalStorageNode()
 1088     {
 1089         return $this->get('optimalStorageNode');
 1090     }
 1091     /**
 1092      * Creates the tasking so I don't have to keep typing it in for each element.
 1093      *
 1094      * @param string $taskName    the name to assign to the tasking
 1095      * @param int    $taskTypeID  the task type id to set the tasking
 1096      * @param string $username    the username to associate with the tasking
 1097      * @param int    $groupID     the Storage Group ID to associate with
 1098      * @param int    $memID       the Storage Node ID to associate with
 1099      * @param bool   $imagingTask if the task is an imaging type
 1100      * @param bool   $shutdown    if the task is to be shutdown once completed
 1101      * @param string $passreset   if the task is a password reset task
 1102      * @param bool   $debug       if the task is a debug task
 1103      * @param bool   $wol         if the task is to wol
 1104      *
 1105      * @return object
 1106      */
 1107     private function _createTasking(
 1108         $taskName,
 1109         $taskTypeID,
 1110         $username,
 1111         $groupID,
 1112         $memID,
 1113         $imagingTask = true,
 1114         $shutdown = false,
 1115         $passreset = false,
 1116         $debug = false,
 1117         $wol = false
 1118     ) {
 1119         $Task = self::getClass('Task')
 1120             ->set('name', $taskName)
 1121             ->set('createdBy', $username)
 1122             ->set('hostID', $this->get('id'))
 1123             ->set('isForced', 0)
 1124             ->set('stateID', self::getQueuedState())
 1125             ->set('typeID', $taskTypeID)
 1126             ->set('storagegroupID', $groupID)
 1127             ->set('storagenodeID', $memID)
 1128             ->set('wol', (string)intval($wol))
 1129             ->set('host', $this)
 1130             ->set('image', $this->getImage())
 1131             ->set('tasktype', new TaskType($taskTypeID))
 1132             ->set('TaskState', new TaskState(self::getQueuedState()))
 1133             ->set('StorageGroup', $this->getImage()->getStorageGroup())
 1134             ->set('StorageNode', new StorageNode());
 1135         if ($imagingTask) {
 1136             $Task->set('imageID', $this->getImage()->get('id'));
 1137         }
 1138         if ($shutdown) {
 1139             $Task->set('shutdown', $shutdown);
 1140         }
 1141         if ($debug) {
 1142             $Task->set('isDebug', $debug);
 1143         }
 1144         if ($passreset) {
 1145             $Task->set('passreset', $passreset);
 1146         }
 1147         return $Task;
 1148     }
 1149     /**
 1150      * Cancels and tasks/jobs for snapins on this host
 1151      *
 1152      * @return void
 1153      */
 1154     private function _cancelJobsSnapinsForHost()
 1155     {
 1156         $SnapinJobs = self::getSubObjectIDs(
 1157             'SnapinJob',
 1158             array(
 1159                 'hostID' => $this->get('id'),
 1160                 'stateID' => self::fastmerge(
 1161                     self::getQueuedStates(),
 1162                     (array)self::getProgressState()
 1163                 )
 1164             )
 1165         );
 1166         self::getClass('SnapinTaskManager')
 1167             ->update(
 1168                 array(
 1169                     'jobID' => $SnapinJobs,
 1170                     'stateID' => self::fastmerge(
 1171                         self::getQueuedStates(),
 1172                         (array)self::getProgressState()
 1173                     )
 1174                 ),
 1175                 '',
 1176                 array(
 1177                     'return' => -9999,
 1178                     'details' => _('Cancelled due to new tasking.'),
 1179                     'stateID' => self::getCancelledState()
 1180                 )
 1181             );
 1182         self::getClass('SnapinJobManager')
 1183             ->update(
 1184                 array('id' => $SnapinJobs),
 1185                 '',
 1186                 array('stateID' => self::getCancelledState())
 1187             );
 1188         $AllTasks = self::getSubObjectIDs(
 1189             'Task',
 1190             array(
 1191                 'stateID' => self::fastmerge(
 1192                     self::getQueuedStates(),
 1193                     (array)self::getProgressState()
 1194                 ),
 1195                 'hostID' => $this->get('id')
 1196             )
 1197         );
 1198         $MyTask = $this->get('task')->get('id');
 1199         self::getClass('TaskManager')
 1200             ->update(
 1201                 array(
 1202                     'id' => array_diff(
 1203                         (array)$AllTasks,
 1204                         (array)$MyTask
 1205                     )
 1206                 ),
 1207                 '',
 1208                 array('stateID' => self::getCancelledState())
 1209             );
 1210     }
 1211     /**
 1212      * Creates the snapin tasking as needed
 1213      *
 1214      * @param int    $snapin The snapin to create tasking on (-1 = all)
 1215      * @param bool   $error  Whether to die on error or not
 1216      * @param object $Task   The task object
 1217      *
 1218      * @return void
 1219      */
 1220     private function _createSnapinTasking(
 1221         $snapin = -1,
 1222         $error = false,
 1223         $Task = false
 1224     ) {
 1225         try {
 1226             $SnapinJob = $this->get('snapinjob');
 1227             if (!$SnapinJob->isValid()) {
 1228                 $SnapinJob
 1229                     ->set('hostID', $this->get('id'))
 1230                     ->set('stateID', self::getQueuedState())
 1231                     ->set(
 1232                         'createdTime',
 1233                         self::niceDate()
 1234                         ->format('Y-m-d H:i:s')
 1235                     );
 1236                 if (!$SnapinJob->save()) {
 1237                     throw new Exception(_('Failed to create Snapin Job'));
 1238                 }
 1239             }
 1240             $insert_fields = array('jobID', 'stateID', 'snapinID');
 1241             $insert_values = array();
 1242             if ($snapin == -1) {
 1243                 $snapin = $this->get('snapins');
 1244             }
 1245             foreach ((array)$snapin as &$snapinID) {
 1246                 $insert_values[] = array(
 1247                     $SnapinJob->get('id'),
 1248                     $this->getQUeuedState(),
 1249                     $snapinID
 1250                 );
 1251                 unset($snapinID);
 1252             }
 1253             if (count($insert_values) > 0) {
 1254                 self::getClass('SnapinTaskManager')
 1255                     ->insertBatch(
 1256                         $insert_fields,
 1257                         $insert_values
 1258                     );
 1259             }
 1260         } catch (Exception $e) {
 1261             if ($error) {
 1262                 $Task->cancel();
 1263                 throw new Exception($e->getMessage());
 1264             }
 1265         }
 1266         return $this;
 1267     }
 1268     /**
 1269      * Creates tasking for the host based on the type
 1270      *
 1271      * @param int    $taskTypeID    the task type
 1272      * @param string $taskName      the name of the task
 1273      * @param bool   $shutdown      whether to shutdown or reboot
 1274      * @param bool   $debug         is this a debug task
 1275      * @param mixed  $deploySnapins snapins to deploy
 1276      * @param bool   $isGroupTask   is the tasking a group task
 1277      * @param string $username      the username creating the task
 1278      * @param string $passreset     username that needs password reset
 1279      * @param bool   $sessionjoin   is this task joining an mc task
 1280      * @param bool   $wol           should we wake the host up
 1281      *
 1282      * @return string
 1283      */
 1284     public function createImagePackage(
 1285         $taskTypeID,
 1286         $taskName = '',
 1287         $shutdown = false,
 1288         $debug = false,
 1289         $deploySnapins = false,
 1290         $isGroupTask = false,
 1291         $username = '',
 1292         $passreset = '',
 1293         $sessionjoin = false,
 1294         $wol = false
 1295     ) {
 1296         if (!$sessionjoin) {
 1297             $taskName .= ' - ' . $this->get('name');
 1298         }
 1299         try {
 1300             if (!$this->isValid()) {
 1301                 throw new Exception(self::$foglang['HostNotValid']);
 1302             }
 1303             $Task = $this->get('task');
 1304             $TaskType = new TaskType($taskTypeID);
 1305             if (!$TaskType->isValid()) {
 1306                 throw new Exception(self::$foglang['TaskTypeNotValid']);
 1307             }
 1308             if ($Task->isValid()) {
 1309                 $iTaskType = $Task->getTaskType()->isImagingTask();
 1310                 if ($iTaskType) {
 1311                     throw new Exception(self::$foglang['InTask']);
 1312                 } elseif ($Task->isSnapinTasking()) {
 1313                     if ($TaskType->get('id') == '13') {
 1314                         $currSnapins = self::getSubObjectIDs(
 1315                             'SnapinTask',
 1316                             array(
 1317                                 'jobID' => $this->get('snapinjob')->get('id'),
 1318                                 'stateID' => self::fastmerge(
 1319                                     (array)$this->getQueuedStates(),
 1320                                     (array)$this->getProgressState()
 1321                                 ),
 1322                             ),
 1323                             'snapinID'
 1324                         );
 1325                         if (!in_array($deploySnapins, $currSnapins)) {
 1326                             $Task
 1327                                 ->set(
 1328                                     'name',
 1329                                     'Multiple Snapin task -- Altered after single'
 1330                                 )
 1331                                 ->set(
 1332                                     'typeID',
 1333                                     12
 1334                                 )->save();
 1335                         }
 1336                     } elseif ($TaskType->get('id') == '12') {
 1337                         $this->_cancelJobsSnapinsForHost();
 1338                     } else {
 1339                         $Task->cancel();
 1340                         $Task = new Task(0);
 1341                         $this->set('task', $Task);
 1342                     }
 1343                 } else {
 1344                     $Task->cancel();
 1345                     $Task = new Task(0);
 1346                     $this->set('task', $Task);
 1347                 }
 1348             }
 1349             unset($iTaskType);
 1350             $Image = $this->getImage();
 1351             $imagingTypes = $TaskType->isImagingTask();
 1352             if ($imagingTypes) {
 1353                 if (!$Image->isValid()) {
 1354                     throw new Exception(self::$foglang['ImageNotValid']);
 1355                 }
 1356                 if (!$Image->get('isEnabled')) {
 1357                     throw new Exception(_('Image is not enabled'));
 1358                 }
 1359                 $StorageGroup = $Image->getStorageGroup();
 1360                 if (!$StorageGroup->isValid()) {
 1361                     throw new Exception(self::$foglang['ImageGroupNotValid']);
 1362                 }
 1363                 if ($TaskType->isCapture()) {
 1364                     $StorageNode = $StorageGroup->getMasterStorageNode();
 1365                 } else {
 1366                     $StorageNode = $this->getOptimalStorageNode();
 1367                 }
 1368                 if (!$StorageNode->isValid()) {
 1369                     $msg = sprintf(
 1370                         '%s %s',
 1371                         _('Could not find any'),
 1372                         _('nodes containing this image')
 1373                     );
 1374                     throw new Exception($msg);
 1375                 }
 1376                 $imageTaskImgID = $this->get('imageID');
 1377                 $hostsWithImgID = self::getSubObjectIDs(
 1378                     'Host',
 1379                     array('imageID' => $imageTaskImgID)
 1380                 );
 1381                 $realImageID = self::getSubObjectIDs(
 1382                     'Host',
 1383                     array('id' => $this->get('id')),
 1384                     'imageID'
 1385                 );
 1386                 if (!in_array($this->get('id'), $hostsWithImgID)) {
 1387                     $this->set(
 1388                         'imageID',
 1389                         array_shift($realImageID)
 1390                     )->save();
 1391                 }
 1392                 $this->set('imageID', $imageTaskImgID);
 1393             }
 1394             $isCapture = $TaskType->isCapture();
 1395             $username = ($username ? $username : self::$FOGUser->get('name'));
 1396             if (!$Task->isValid()) {
 1397                 $Task = $this->_createTasking(
 1398                     $taskName,
 1399                     $taskTypeID,
 1400                     $username,
 1401                     $imagingTypes ? $StorageGroup->get('id') : 0,
 1402                     $imagingTypes ? $StorageNode->get('id') : 0,
 1403                     $imagingTypes,
 1404                     $shutdown,
 1405                     $passreset,
 1406                     $debug,
 1407                     $wol
 1408                 );
 1409                 $Task->set('imageID', $this->get('imageID'));
 1410                 if (!$Task->save()) {
 1411                     throw new Exception(self::$foglang['FailedTask']);
 1412                 }
 1413                 $this->set('task', $Task);
 1414             }
 1415             if ($TaskType->isSnapinTask()) {
 1416                 if ($deploySnapins === true) {
 1417                     $deploySnapins = -1;
 1418                 }
 1419                 $mac = $this->get('mac');
 1420                 if ($deploySnapins) {
 1421                     $this->_createSnapinTasking(
 1422                         $deploySnapins,
 1423                         $TaskType->isSnapinTasking(),
 1424                         $Task
 1425                     );
 1426                 }
 1427             }
 1428             if ($TaskType->isMulticast()) {
 1429                 $multicastTaskReturn = function (&$MulticastSession) {
 1430                     if (!$MulticastSession->isValid()) {
 1431                         return;
 1432                     }
 1433                     return $MulticastSession;
 1434                 };
 1435                 $assoc = false;
 1436                 $showStates = self::fastmerge(
 1437                     self::getQueuedStates(),
 1438                     (array)self::getProgressState()
 1439                 );
 1440                 if ($sessionjoin) {
 1441                     $MCSessions = self::getClass('MulticastSessionManager')
 1442                         ->find(
 1443                             array(
 1444                                 'name' => $taskName,
 1445                                 'stateID' => $showStates
 1446                             )
 1447                         );
 1448                     $assoc = true;
 1449                 } else {
 1450                     $MCSessions = self::getClass('MulticastSessionManager')
 1451                         ->find(
 1452                             array(
 1453                                 'image' => $Image->get('id'),
 1454                                 'stateID' => $showStates
 1455                             )
 1456                         );
 1457                 }
 1458                 $MultiSessJoin = array_map(
 1459                     $multicastTaskReturn,
 1460                     $MCSessions
 1461                 );
 1462                 $MultiSessJoin = array_filter($MultiSessJoin);
 1463                 $MultiSessJoin = array_values($MultiSessJoin);
 1464                 if (is_array($MultiSessJoin) && count($MultiSessJoin)) {
 1465                     $MulticastSession = array_shift($MultiSessJoin);
 1466                 }
 1467                 unset($MultiSessJoin);
 1468                 if ($MulticastSession instanceof MulticastSession
 1469                     && $MulticastSession->isValid()
 1470                 ) {
 1471                     $assoc = true;
 1472                 } else {
 1473                     $port = self::getSetting('FOG_UDPCAST_STARTINGPORT');
 1474                     $portOverride = self::getSetting('FOG_MULTICAST_PORT_OVERRIDE');
 1475                     $MulticastSession = self::getClass('MulticastSession')
 1476                         ->set('name', $taskName)
 1477                         ->set('port', ($portOverride ? $portOverride : $port))
 1478                         ->set('logpath', $this->getImage()->get('path'))
 1479                         ->set('image', $this->getImage()->get('id'))
 1480                         ->set('interface', $StorageNode->get('interface'))
 1481                         ->set('stateID', 0)
 1482                         ->set('starttime', self::niceDate()->format('Y-m-d H:i:s'))
 1483                         ->set('percent', 0)
 1484                         ->set('isDD', $this->getImage()->get('imageTypeID'))
 1485                         ->set('storagegroupID', $StorageNode->get('storagegroupID'))
 1486                         ->set('clients', -1);
 1487                     if ($MulticastSession->save()) {
 1488                         $assoc = true;
 1489                         if (!self::getSetting('FOG_MULTICAST_PORT_OVERRIDE')) {
 1490                             $randomnumber = mt_rand(24576, 32766)*2;
 1491                             while ($randomnumber
 1492                                 == $MulticastSession->get('port')
 1493                             ) {
 1494                                 $randomnumber = mt_rand(24576, 32766)*2;
 1495                             }
 1496                             self::setSetting(
 1497                                 'FOG_UDPCAST_STARTINGPORT',
 1498                                 $randomnumber
 1499                             );
 1500                         }
 1501                     }
 1502                 }
 1503                 if ($assoc) {
 1504                     self::getClass('MulticastSessionAssociation')
 1505                         ->set('msID', $MulticastSession->get('id'))
 1506                         ->set('taskID', $Task->get('id'))
 1507                         ->save();
 1508                 }
 1509             }
 1510             if ($wol) {
 1511                 $this->wakeOnLAN();
 1512             }
 1513         } catch (Exception $e) {
 1514             throw new Exception($e->getMessage());
 1515         }
 1516         if ($taskTypeID == 14) {
 1517             $Task->destroy();
 1518         }
 1519         $str = '<li>';
 1520         $str .= '<a href="#">';
 1521         $str .= $this->get('name');
 1522         $str .= ' &ndash; ';
 1523         $str .= $this->getImage()->get('name');
 1524         $str .= '</a>';
 1525         $str .= '</li>';
 1526         return $str;
 1527     }
 1528     /**
 1529      * Returns task if host image is valid
 1530      *
 1531      * @return Task
 1532      */
 1533     public function getImageMemberFromHostID()
 1534     {
 1535         try {
 1536             $Image = $this->getImage();
 1537             if (!$Image->isValid()) {
 1538                 throw new Exception(_('No valid Image defined for this host'));
 1539             }
 1540             if (!$Image->get('isEnabled')) {
 1541                 throw new Exception(_('Image is not enabled'));
 1542             }
 1543             $StorageGroup = $Image->getStorageGroup();
 1544             if (!$StorageGroup->isValid()) {
 1545                 throw new Exception('No StorageGroup defined for this host');
 1546             }
 1547             $Task = self::getClass('Task')
 1548                 ->set('hostID', $this->get('id'))
 1549                 ->set('storagegroupID', $StorageGroup->get('id'))
 1550                 ->set(
 1551                     'storagenodeID',
 1552                     $StorageGroup
 1553                         ->getOptimalStorageNode()
 1554                         ->get('id')
 1555                 )
 1556                 ->set('imageID', $Image->get('id'));
 1557         } catch (Exception $e) {
 1558             self::error(
 1559                 sprintf(
 1560                     '%s():xError: %s',
 1561                     __FUNCTION__,
 1562                     $e->getMessage()
 1563                 )
 1564             );
 1565             $Task = false;
 1566         }
 1567         return $Task;
 1568     }
 1569     /**
 1570      * Clears virus records for the host
 1571      *
 1572      * @return object
 1573      */
 1574     public function clearAVRecordsForHost()
 1575     {
 1576         self::getClass('VirusManager')
 1577             ->destroy(
 1578                 array('mac' => $this->getMyMacs())
 1579             );
 1580         return $this;
 1581     }
 1582     /**
 1583      * Wakes this host up
 1584      *
 1585      * @return object
 1586      */
 1587     public function wakeOnLAN()
 1588     {
 1589         self::wakeUp($this->getMyMacs());
 1590         return $this;
 1591     }
 1592     /**
 1593      * Adds additional macs
 1594      *
 1595      * @param array $addArray the macs to add
 1596      * @param bool  $pending  should it be added as a pending mac
 1597      *
 1598      * @return object
 1599      */
 1600     public function addAddMAC($addArray, $pending = false)
 1601     {
 1602         $addArray = array_map('strtolower', (array)$addArray);
 1603         $addArray = self::parseMacList($addArray);
 1604         $addTo = $pending ? 'pendingMACs' : 'additionalMACs';
 1605         foreach ((array)$addArray as &$mac) {
 1606             $this->add($addTo, $mac);
 1607             unset($mac);
 1608         }
 1609         return $this;
 1610     }
 1611     /**
 1612      * Moves pending macs to additional macs
 1613      *
 1614      * @param array $addArray the macs to move
 1615      *
 1616      * @return object
 1617      */
 1618     public function addPendtoAdd($addArray = false)
 1619     {
 1620         $lowerAndTrim = function (&$MAC) {
 1621             return trim(strtolower($MAC));
 1622         };
 1623         $PendMACs = array_map($lowerAndTrim, (array)$this->get('pendingMACs'));
 1624         $MACs = array_map($lowerAndTrim, (array)$addArray);
 1625         if ($addArray === false) {
 1626             $matched = array_intersect(
 1627                 (array)$PendMACs,
 1628                 (array)$MACs
 1629             );
 1630         } else {
 1631             $matched = $PendMACs;
 1632         }
 1633         unset($MACs, $PendMACs);
 1634         return $this->addAddMAC($matched)->removePendMAC($matched);
 1635     }
 1636     /**
 1637      * Removes additional macs
 1638      *
 1639      * @param array $removeArray the macs to remove
 1640      *
 1641      * @return object
 1642      */
 1643     public function removeAddMAC($removeArray)
 1644     {
 1645         foreach ((array)$removeArray as &$mac) {
 1646             if (!$mac instanceof MACAddress) {
 1647                 $mac = new MACAddress($mac);
 1648             }
 1649             if (!$mac->isValid()) {
 1650                 continue;
 1651             }
 1652             $this->remove('additionalMACs', $mac);
 1653             unset($mac);
 1654         }
 1655         return $this;
 1656     }
 1657     /**
 1658      * Removes pending macs
 1659      *
 1660      * @param array $removeArray the macs to remove
 1661      *
 1662      * @return object
 1663      */
 1664     public function removePendMAC($removeArray)
 1665     {
 1666         foreach ((array)$removeArray as &$mac) {
 1667             if (!$mac instanceof MACAddress) {
 1668                 $mac = new MACAddress($mac);
 1669             }
 1670             if (!$mac->isValid()) {
 1671                 continue;
 1672             }
 1673             $this->remove('pendingMACs', $mac);
 1674             unset($mac);
 1675         }
 1676         return $this;
 1677     }
 1678     /**
 1679      * Adds primary mac
 1680      *
 1681      * @param string $mac the mac to make as primary
 1682      *
 1683      * @return object
 1684      */
 1685     public function addPriMAC($mac)
 1686     {
 1687         $mac = self::parseMacList($mac);
 1688         if (count($mac) < 1) {
 1689             throw new Exception(_('No viable macs to use'));
 1690         }
 1691         if (is_array($mac) && count($mac) > 0) {
 1692             $mac = array_shift($mac);
 1693         }
 1694         $host = $mac->getHost();
 1695         if ($host instanceof Host && $host->isValid()) {
 1696             throw new Exception(
 1697                 sprintf(
 1698                     "%s: %s",
 1699                     _('MAC address is already in use by another host'),
 1700                     $host->get('name')
 1701                 )
 1702             );
 1703         }
 1704         return $this->set('mac', $mac);
 1705     }
 1706     /**
 1707      * Adds pending mac
 1708      *
 1709      * @param string $mac the mac to add
 1710      *
 1711      * @return obect
 1712      */
 1713     public function addPendMAC($mac)
 1714     {
 1715         return $this->addAddMAC($mac, true);
 1716     }
 1717     /**
 1718      * Adds printers to the host
 1719      *
 1720      * @param array $addArray the printers to add
 1721      *
 1722      * @return object
 1723      */
 1724     public function addPrinter($addArray)
 1725     {
 1726         return $this->addRemItem(
 1727             'printers',
 1728             (array)$addArray,
 1729             'merge'
 1730         );
 1731     }
 1732     /**
 1733      * Removes printers from the host
 1734      *
 1735      * @param array $removeArray the printers to remove
 1736      *
 1737      * @return object
 1738      */
 1739     public function removePrinter($removeArray)
 1740     {
 1741         return $this->addRemItem(
 1742             'printers',
 1743             (array)$removeArray,
 1744             'diff'
 1745         );
 1746     }
 1747     /**
 1748      * Adds snapins to the host
 1749      *
 1750      * @param array $addArray the snapins to add
 1751      *
 1752      * @throws Exception
 1753      * @return object
 1754      */
 1755     public function addSnapin($addArray)
 1756     {
 1757         $limit = self::getSetting('FOG_SNAPIN_LIMIT');
 1758         if ($limit > 0) {
 1759             $snapinCount = self::getClass('SnapinManager')
 1760                 ->count(
 1761                     array('id' => $this->get('snapins'))
 1762                 );
 1763             if ($snapinCount >= $limit || count($addArray) > $limit) {
 1764                 $limitstr = sprintf(
 1765                     '%s%s %s',
 1766                     _('snapin'),
 1767                     $limit == 1 ? '' : 's',
 1768                     _('per host')
 1769                 );
 1770                 throw new Exception(
 1771                     sprintf(
 1772                         '%s %d %s',
 1773                         _('You are only allowed to assign'),
 1774                         $limit,
 1775                         $limitstr
 1776                     )
 1777                 );
 1778             }
 1779         }
 1780         return $this->addRemItem(
 1781             'snapins',
 1782             (array)$addArray,
 1783             'merge'
 1784         );
 1785     }
 1786     /**
 1787      * Removes snapins from the host
 1788      *
 1789      * @param array $removeArray the snapins to remove
 1790      *
 1791      * @return object
 1792      */
 1793     public function removeSnapin($removeArray)
 1794     {
 1795         return $this->addRemItem(
 1796             'snapins',
 1797             (array)$removeArray,
 1798             'diff'
 1799         );
 1800     }
 1801     /**
 1802      * Adds modules to the host
 1803      *
 1804      * @param array $addArray the modules to add
 1805      *
 1806      * @return object
 1807      */
 1808     public function addModule($addArray)
 1809     {
 1810         return $this->addRemItem(
 1811             'modules',
 1812             (array)$addArray,
 1813             'merge'
 1814         );
 1815     }
 1816     /**
 1817      * Removes modules from the host
 1818      *
 1819      * @param array $removeArray the modules to remove
 1820      *
 1821      * @return object
 1822      */
 1823     public function removeModule($removeArray)
 1824     {
 1825         return $this->addRemItem(
 1826             'modules',
 1827             (array)$removeArray,
 1828             'diff'
 1829         );
 1830     }
 1831     /**
 1832      * Adds powermanagement tasks to the host
 1833      *
 1834      * @param array $addArray the powermanagement tasks to add
 1835      *
 1836      * @return object
 1837      */
 1838     public function addPowerManagement($addArray)
 1839     {
 1840         return $this->addRemItem(
 1841             'powermanagementtasks',
 1842             (array)$addArray,
 1843             'merge'
 1844         );
 1845     }
 1846     /**
 1847      * Removes powermanagement tasks from the host
 1848      *
 1849      * @param array $removeArray the powermanagement tasks to remove
 1850      *
 1851      * @return object
 1852      */
 1853     public function removePowerManagement($removeArray)
 1854     {
 1855         return $this->addRemItem(
 1856             'powermanagementtasks',
 1857             (array)$removeArray,
 1858             'diff'
 1859         );
 1860     }
 1861     /**
 1862      * Returns the macs
 1863      *
 1864      * @param bool $justme should only return this or all macs
 1865      *
 1866      * @return array
 1867      */
 1868     public function getMyMacs($justme = true)
 1869     {
 1870         if ($justme) {
 1871             return self::getSubObjectIDs(
 1872                 'MACAddressAssociation',
 1873                 array('hostID' => $this->get('id')),
 1874                 'mac'
 1875             );
 1876         }
 1877         return self::getSubObjectIDs(
 1878             'MACAddressAssociation',
 1879             '',
 1880             'mac'
 1881         );
 1882     }
 1883     /**
 1884      * Sets the ignore status of a mac for either image or client ignore
 1885      *
 1886      * @param array $imageIgnore  to ignore for imaging
 1887      * @param array $clientIgnore to ignore for client
 1888      *
 1889      * @return object
 1890      */
 1891     public function ignore($imageIgnore, $clientIgnore)
 1892     {
 1893         $MyMACs = $this->getMyMacs();
 1894         $myMACs = $igMACs = $cgMACs = array();
 1895         $macaddress = function (&$mac) {
 1896             if (!$mac instanceof MACAddress) {
 1897                 $mac = new MACAddress($mac);
 1898             }
 1899             if (!$mac->isValid()) {
 1900                 return;
 1901             }
 1902             return $mac->__toString();
 1903         };
 1904         $myMACs = array_map($macaddress, (array)$MyMACs);
 1905         $igMACs = array_map($macaddress, (array)$imageIgnore);
 1906         $cgMACs = array_map($macaddress, (array)$clientIgnore);
 1907         $myMACs = array_filter($myMACs);
 1908         $igMACs = array_filter($igMACs);
 1909         $cgMACs = array_filter($cgMACs);
 1910         $myMACs = array_unique($myMACs);
 1911         $igMACs = array_unique($igMACs);
 1912         $cgMACs = array_unique($cgMACs);
 1913         self::getClass('MACAddressAssociationManager')
 1914             ->update(
 1915                 array(
 1916                     'mac' => array_diff(
 1917                         (array)$myMACs,
 1918                         (array)$igMACs
 1919                     ),
 1920                     'hostID' => $this->get('id')
 1921                 ),
 1922                 '',
 1923                 array('imageIgnore' => 0)
 1924             );
 1925         self::getClass('MACAddressAssociationManager')
 1926             ->update(
 1927                 array(
 1928                     'mac' => array_diff(
 1929                         (array)$myMACs,
 1930                         (array)$cgMACs
 1931                     ),
 1932                     'hostID'=>$this->get('id')
 1933                 ),
 1934                 '',
 1935                 array('clientIgnore' => 0)
 1936             );
 1937         if (count($igMACs) > 0) {
 1938             self::getClass('MACAddressAssociationManager')
 1939                 ->update(
 1940                     array(
 1941                         'mac' => $igMACs,
 1942                         'hostID' => $this->get('id')
 1943                     ),
 1944                     '',
 1945                     array('imageIgnore' => 1)
 1946                 );
 1947         }
 1948         if (count($cgMACs) > 0) {
 1949             self::getClass('MACAddressAssociationManager')
 1950                 ->update(
 1951                     array(
 1952                         'mac' => $cgMACs,
 1953                         'hostID'=>$this->get('id')
 1954                     ),
 1955                     '',
 1956                     array('clientIgnore' => 1)
 1957                 );
 1958         }
 1959     }
 1960     /**
 1961      * Adds host to the selected group
 1962      * alias to addHost method
 1963      *
 1964      * @param array $addArray the groups to add
 1965      *
 1966      * @return object
 1967      */
 1968     public function addGroup($addArray)
 1969     {
 1970         return $this->addHost($addArray);
 1971     }
 1972     /**
 1973      * Removes host from the selected group
 1974      * alias to removeHost method
 1975      *
 1976      * @param array $removeArray the groups to remove
 1977      *
 1978      * @return object
 1979      */
 1980     public function removeGroup($removeArray)
 1981     {
 1982         return $this->removeHost($removeArray);
 1983     }
 1984     /**
 1985      * Adds host to the selected group
 1986      *
 1987      * @param array $addArray the groups to add
 1988      *
 1989      * @return object
 1990      */
 1991     public function addHost($addArray)
 1992     {
 1993         return $this->addRemItem(
 1994             'groups',
 1995             (array)$addArray,
 1996             'merge'
 1997         );
 1998     }
 1999     /**
 2000      * Removes host from the selected group
 2001      *
 2002      * @param array $removeArray the groups to remove
 2003      *
 2004      * @return object
 2005      */
 2006     public function removeHost($removeArray)
 2007     {
 2008         return $this->addRemItem(
 2009             'groups',
 2010             (array)$removeArray,
 2011             'diff'
 2012         );
 2013     }
 2014     /**
 2015      * Tells if the mac is client ignored
 2016      *
 2017      * @param string $mac the mac to test
 2018      *
 2019      * @return string
 2020      */
 2021     public function clientMacCheck($mac = false)
 2022     {
 2023         if ($mac) {
 2024             if (!$mac instanceof MACAddress) {
 2025                 $mac = new MACAddress($mac);
 2026             }
 2027             if ($mac->isClientIgnored()) {
 2028                 return ' checked';
 2029             }
 2030             return '';
 2031         }
 2032         return $this->get('mac')->isClientIgnored() ? ' checked' : '';
 2033     }
 2034     /**
 2035      * Tells if the mac is image ignored
 2036      *
 2037      * @param string $mac the mac to test
 2038      *
 2039      * @return string
 2040      */
 2041     public function imageMacCheck($mac = false)
 2042     {
 2043         if ($mac) {
 2044             if (!$mac instanceof MACAddress) {
 2045                 $mac = new MACAddress($mac);
 2046             }
 2047             if ($mac->isImageIgnored()) {
 2048                 return ' checked';
 2049             }
 2050             return '';
 2051         }
 2052         return $this->get('mac')->isImageIgnored() ? ' checked' : '';
 2053     }
 2054     /**
 2055      * Sets the host settings for AD (mainly)
 2056      *
 2057      * @param mixed  $useAD      whether to perform joins
 2058      * @param string $domain     the domain to associate
 2059      * @param string $ou         the ou to bind to
 2060      * @param string $user       the user to perform join with
 2061      * @param string $pass       the pass to perform join with
 2062      * @param bool   $override   should the host fields override whats passed
 2063      * @param bool   $nosave     should we save automatically
 2064      * @param string $legacy     the legacy client ad pass string
 2065      * @param string $productKey the product key for the host to activate
 2066      * @param mixed  $enforce    should the host perform changes forcibly
 2067      *
 2068      * @return object
 2069      */
 2070     public function setAD(
 2071         $useAD = '',
 2072         $domain = '',
 2073         $ou = '',
 2074         $user = '',
 2075         $pass = '',
 2076         $override = false,
 2077         $nosave = false,
 2078         $legacy = '',
 2079         $productKey = '',
 2080         $enforce = ''
 2081     ) {
 2082         $adpasspat = "/^\*{32}$/";
 2083         $pass = (preg_match($adpasspat, $pass) ? $this->get('ADPass') : $pass);
 2084         if ($this->get('id')) {
 2085             if (!$override) {
 2086                 if (empty($useAD)) {
 2087                     $useAD = $this->get('useAD');
 2088                 }
 2089                 if (empty($domain)) {
 2090                     $domain = trim($this->get('ADDomain'));
 2091                 }
 2092                 if (empty($ou)) {
 2093                     $ou = trim($this->get('ADOU'));
 2094                 }
 2095                 if (empty($user)) {
 2096                     $user = trim($this->get('ADUser'));
 2097                 }
 2098                 if (empty($pass)) {
 2099                     $pass = trim($this->get('ADPass'));
 2100                 }
 2101                 if (empty($legacy)) {
 2102                     $legacy = trim($this->get('ADPassLegacy'));
 2103                 }
 2104                 if (empty($productKey)) {
 2105                     $productKey = trim($this->get('productKey'));
 2106                 }
 2107                 if (empty($enforce)) {
 2108                     $enforce = (int)$this->get('enforce');
 2109                 }
 2110             }
 2111         }
 2112         if ($pass) {
 2113             $pass = trim($pass);
 2114         }
 2115         $this->set('useAD', $useAD)
 2116             ->set('ADDomain', trim($domain))
 2117             ->set('ADOU', trim($ou))
 2118             ->set('ADUser', trim($user))
 2119             ->set('ADPass', $pass)
 2120             ->set('ADPassLegacy', $legacy)
 2121             ->set('productKey', trim($productKey))
 2122             ->set('enforce', (string)$enforce);
 2123         return $this;
 2124     }
 2125     /**
 2126      * Returns the hosts image object
 2127      *
 2128      * @return Image
 2129      */
 2130     public function getImage()
 2131     {
 2132         return $this->get('imagename');
 2133     }
 2134     /**
 2135      * Returns the hosts image name
 2136      *
 2137      * @return string
 2138      */
 2139     public function getImageName()
 2140     {
 2141         return $this
 2142             ->get('imagename')
 2143             ->get('name');
 2144     }
 2145     /**
 2146      * Returns the hosts image os name
 2147      *
 2148      * @return string
 2149      */
 2150     public function getOS()
 2151     {
 2152         return $this->getImage()->getOS()->get('name');
 2153     }
 2154     /**
 2155      * Returns the snapinjob
 2156      *
 2157      * @return SnapinJob
 2158      */
 2159     public function getActiveSnapinJob()
 2160     {
 2161         return $this->get('snapinjob');
 2162     }
 2163     /**
 2164      * Translates the ping status code to string
 2165      *
 2166      * @return string
 2167      */
 2168     public function getPingCodeStr()
 2169     {
 2170         $val =  (int)$this->get('pingstatus');
 2171         $socketstr = socket_strerror($val);
 2172         $strtoupdate = '<i class="icon-ping-%s fa fa-%s %s'
 2173             . '" data-toggle="tooltip" '
 2174             . 'data-placement="right" '
 2175             . 'title="%s'
 2176             . '"></i>';
 2177 
 2178         ob_start();
 2179         switch ($val) {
 2180                 case 0:
 2181                         printf($strtoupdate, 'windows', 'windows', 'green', 'Windows');
 2182                         break;
 2183                 case 111:
 2184                         $taskID = self::getSubObjectIDs(
 2185                             'Task',
 2186                             array('hostID' => $this->get('id'),
 2187                                       'stateID' => 2
 2188                                 ),
 2189                             'id'
 2190                         );
 2191                         if (is_null($taskID)) {
 2192                             printf($strtoupdate, 'linux', 'linux', 'blue', 'Linux');
 2193                         } else {
 2194                             printf($strtoupdate, 'fos', 'cogs', 'green', 'FOS');
 2195                         }
 2196 
 2197                         break;
 2198                 default:
 2199                         printf($strtoupdate, 'down', 'exclamation-circle', 'red', 'Unknown');
 2200         }
 2201         return ob_get_clean();
 2202     }
 2203 }