"Fossies" - the Fresh Open Source Software Archive

Member "fogproject-1.5.9/packages/web/lib/fog/fogmanagercontroller.class.php" (13 Sep 2020, 44219 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 "fogmanagercontroller.class.php": 1.5.8_vs_1.5.9.

    1 <?php
    2 /**
    3  * FOG Manager Controller, main object mass getter.
    4  *
    5  * PHP version 5
    6  *
    7  * @category FOGManagerController
    8  * @package  FOGProject
    9  * @author   Tom Elliott <tommygunsster@gmail.com>
   10  * @license  http://opensource.org/licenses/gpl-3.0 GPLv3
   11  * @link     https://fogproject.org
   12  */
   13 /**
   14  * FOG Manager Controller, main object mass getter.
   15  *
   16  * @category FOGManagerController
   17  * @package  FOGProject
   18  * @author   Tom Elliott <tommygunsster@gmail.com>
   19  * @license  http://opensource.org/licenses/gpl-3.0 GPLv3
   20  * @link     https://fogproject.org
   21  */
   22 abstract class FOGManagerController extends FOGBase
   23 {
   24     /**
   25      * The main class for the object.
   26      *
   27      * @var string
   28      */
   29     protected $childClass;
   30     /**
   31      * The table name for the object.
   32      *
   33      * @var string
   34      */
   35     protected $databaseTable;
   36     /**
   37      * The common names and fields.
   38      *
   39      * @var array
   40      */
   41     protected $databaseFields = array();
   42     /**
   43      * The Flipped fields.
   44      *
   45      * @var array
   46      */
   47     protected $databaseFieldsFlipped = array();
   48     /**
   49      * The required fields.
   50      *
   51      * @var array
   52      */
   53     protected $databaseFieldsRequired = array();
   54     /**
   55      * The Class relationships.
   56      *
   57      * @var array
   58      */
   59     protected $databaseFieldClassRelationships = array();
   60     /**
   61      * The additional fields.
   62      *
   63      * @var array
   64      */
   65     protected $additionalFields = array();
   66     /**
   67      * The load template.
   68      *
   69      * SELECT <field(s)> FROM `<table>` <join> <where>
   70      *
   71      * @var string
   72      */
   73     protected $loadQueryTemplate = 'SELECT %s FROM `%s` %s %s %s %s %s';
   74     /**
   75      * The count template.
   76      *
   77      * @var string
   78      */
   79     protected $countQueryTemplate = 'SELECT COUNT(`%s`.`%s`) AS `total` FROM `%s`%s LIMIT 1';
   80     /**
   81      * The update template.
   82      *
   83      * @var string
   84      */
   85     protected $updateQueryTemplate = 'UPDATE `%s` SET %s %s';
   86     /**
   87      * The destroy template.
   88      *
   89      * @var string
   90      */
   91     protected $destroyQueryTemplate = 'DELETE FROM `%s` WHERE `%s`.`%s` IN (%s)';
   92     /**
   93      * The exists template.
   94      *
   95      * @var string
   96      */
   97     protected $existsQueryTemplate = 'SELECT COUNT(`%s`.`%s`) AS `total` FROM `%s` WHERE `%s`.`%s`=%s AND `%s`.`%s` <> %s';
   98     /**
   99      * The insert batch template.
  100      *
  101      * @var string
  102      */
  103     protected $insertBatchTemplate = 'INSERT INTO `%s` (`%s`) VALUES %s ON DUPLICATE KEY UPDATE %s';
  104     /**
  105      * The distinct template.
  106      *
  107      * @var string
  108      */
  109     protected $distinctTemplate = 'SELECT COUNT(DISTINCT `%s`.`%s`) AS `total` FROM `%s`%s LIMIT 1';
  110     /**
  111      * Initializes the manager class.
  112      */
  113     public function __construct()
  114     {
  115         parent::__construct();
  116         $this->childClass = preg_replace(
  117             '#_?Manager$#',
  118             '',
  119             get_class($this)
  120         );
  121         $classVars = self::getClass(
  122             $this->childClass,
  123             '',
  124             true
  125         );
  126         $classGet = array(
  127             'databaseTable',
  128             'databaseFields',
  129             'additionalFields',
  130             'databaseFieldsRequired',
  131             'databaseFieldClassRelationships',
  132         );
  133         $this->databaseTable = &$classVars[$classGet[0]];
  134         $this->databaseFields = &$classVars[$classGet[1]];
  135         $this->additionalFields = &$classVars[$classGet[2]];
  136         $this->databaseFieldsRequired = &$classVars[$classGet[3]];
  137         $this->databaseFieldClassRelationships = &$classVars[$classGet[4]];
  138         $this->databaseFieldsFlipped = array_flip($this->databaseFields);
  139         unset($classGet);
  140     }
  141     /**
  142      * Finds items related to the main object.
  143      *
  144      * @param array  $findWhere     what to find
  145      * @param string $whereOperator how to combine where items
  146      * @param string $orderBy       how to order fields
  147      * @param string $sort          how the sort order
  148      * @param string $compare       how to compare
  149      * @param string $groupBy       how to group fields
  150      * @param bool   $not           use not operator
  151      * @param mixed  $idField       what fields to get
  152      * @param bool   $onecompare    second where uses AND
  153      * @param string $filter        array function for filter
  154      *
  155      * @return array
  156      */
  157     public function find(
  158         $findWhere = array(),
  159         $whereOperator = 'AND',
  160         $orderBy = 'name',
  161         $sort = 'ASC',
  162         $compare = '=',
  163         $groupBy = false,
  164         $not = false,
  165         $idField = false,
  166         $onecompare = true,
  167         $filter = 'array_unique'
  168     ) {
  169         // Fail safe defaults
  170         if (empty($findWhere)) {
  171             $findWhere = array();
  172         }
  173         if (empty($whereOperator)) {
  174             $whereOperator = 'AND';
  175         }
  176         if (empty($sort)) {
  177             $sort = 'ASC';
  178         }
  179         $this->orderBy($orderBy);
  180         if (empty($compare)) {
  181             $compare = '=';
  182         }
  183         $findVals = array();
  184         $not = (
  185             $not ?
  186             ' NOT ' :
  187             ' '
  188         );
  189         $whereArray = $whereArrayAnd = array();
  190         if (count($findWhere) > 0) {
  191             $count = 0;
  192             foreach ($findWhere as $field => &$value) {
  193                 $key = trim($field);
  194                 if (!$value) {
  195                     $value = array(
  196                         '0',
  197                         0,
  198                         null,
  199                         '',
  200                     );
  201                 }
  202                 if (is_array($value) && count($value) > 0) {
  203                     foreach ($value as $i => &$val) {
  204                         if (is_string($val)) {
  205                             $val = trim($val);
  206                         }
  207                         // Define the key
  208                         $k = sprintf(
  209                             '%s_%d',
  210                             $key,
  211                             $i
  212                         );
  213                         // Define param keys
  214                         $findKeys[] = sprintf(
  215                             ':%s',
  216                             $k
  217                         );
  218                         // Define the param array
  219                         $findVals[$k] = $val;
  220                         unset($val);
  221                     }
  222                     $whereArray[] = sprintf(
  223                         '`%s`.`%s`%sIN (%s)',
  224                         $this->databaseTable,
  225                         $this->databaseFields[$field],
  226                         $not,
  227                         implode(',', $findKeys)
  228                     );
  229                     unset($findKeys);
  230                 } else {
  231                     if (is_array($value)) {
  232                         $value = '';
  233                     }
  234                     $value = trim($value);
  235                     $k = sprintf(
  236                         '%s',
  237                         $key
  238                     );
  239                     // Define the param keys
  240                     $findKey = sprintf(
  241                         ':%s',
  242                         $key
  243                     );
  244                     // Define the param array
  245                     $findVals[$k] = $value;
  246                     $whereArray[] = sprintf(
  247                         '`%s`.`%s`%s%s',
  248                         $this->databaseTable,
  249                         $this->databaseFields[$field],
  250                         (
  251                             preg_match('#%#', (string) $value) ?
  252                             sprintf(' %sLIKE ', $not) :
  253                             sprintf(
  254                                 '%s%s',
  255                                 (
  256                                     trim($not) ? '!' : ''
  257                                 ),
  258                                 (
  259                                     $onecompare ?
  260                                     (!$count ? $compare : '=') :
  261                                     $compare
  262                                 )
  263                             )
  264                         ),
  265                         $findKey
  266                     );
  267                 }
  268                 ++$count;
  269                 unset($value);
  270             }
  271         }
  272         if (!is_array($orderBy)) {
  273             $orderBy = sprintf(
  274                 'ORDER BY %s`%s`.`%s`%s %s',
  275                 ($orderBy == 'name' ? 'LOWER(' : ''),
  276                 $this->databaseTable,
  277                 $this->databaseFields[$orderBy],
  278                 ($orderBy == 'name' ? ')' : ''),
  279                 $sort
  280             );
  281             if ($groupBy) {
  282                 $groupBy = sprintf(
  283                     'GROUP BY `%s`.`%s`',
  284                     $this->databaseTable,
  285                     $this->databaseFields[$groupBy]
  286                 );
  287             } else {
  288                 $groupBy = '';
  289             }
  290         } else {
  291             $orderString = '';
  292             foreach ((array)$orderBy as $i => &$order) {
  293                 $orderString .= sprintf(
  294                     '`%s`.`%s` %s,',
  295                     $this->databaseTable,
  296                     $this->databaseFields[$order],
  297                     is_array($sort) ? $sort[$i] : $sort
  298                 );
  299                 unset($order);
  300             }
  301             $orderString = trim($orderString, ','.$sort);
  302             $orderBy = sprintf(
  303                 'ORDER BY %s ',
  304                 $orderString
  305             );
  306         }
  307         $join = $whereArrayAnd = array();
  308         $c = null;
  309         self::getClass($this->childClass)->buildQuery(
  310             $join,
  311             $whereArrayAnd,
  312             $c,
  313             $not,
  314             $compare
  315         );
  316         $join = array_filter((array) $join);
  317         $join = implode((array) $join);
  318         $knownEnable = array(
  319             'Image',
  320             'Snapin',
  321             'StorageNode'
  322         );
  323         $nonEnable = !(in_array($this->childClass, $knownEnable));
  324         $isEnabled = array_key_exists(
  325             'isEnabled',
  326             $this->databaseFields
  327         );
  328         if ($nonEnable && $isEnabled) {
  329             $isEnabled = sprintf(
  330                 '`%s`=1',
  331                 $this->databaseFields['isEnabled']
  332             );
  333         }
  334         if ($nonEnable && $isEnabled) {
  335             $findVals['isEnabled'] = 1;
  336             $isEnabled = sprintf(
  337                 '`%s`=:isEnabled',
  338                 $this->databaseFields['isEnabled']
  339             );
  340         }
  341         $idFields = array();
  342         foreach ((array) $idField as &$id) {
  343             $id = trim($id);
  344             if (isset($this->databaseFields[$id])) {
  345                 $idFields += (array) $this->databaseFields[$id];
  346             }
  347             unset($id);
  348         }
  349         $idFields = array_filter($idFields);
  350         $idField = $idFields;
  351         unset($idFields);
  352         $query = sprintf(
  353             $this->loadQueryTemplate,
  354             (
  355                 count($idField) > 0 ?
  356                 sprintf('`%s`', implode('`,`', (array) $idField)) :
  357                 '*'
  358             ),
  359             $this->databaseTable,
  360             $join,
  361             (
  362                 count($whereArray) > 0 ?
  363                 sprintf(
  364                     ' WHERE %s%s',
  365                     implode(" $whereOperator ", (array) $whereArray),
  366                     (
  367                         $isEnabled ?
  368                         sprintf(' AND %s', $isEnabled) :
  369                         ''
  370                     )
  371                 ) :
  372                 (
  373                     $isEnabled ?
  374                     sprintf(' WHERE %s', $isEnabled) :
  375                     ''
  376                 )
  377             ),
  378             (
  379                 count($whereArrayAnd) > 0 ?
  380                 (
  381                     count($whereArray) > 0 ?
  382                     sprintf(
  383                         'AND %s',
  384                         implode(" $whereOperator ", (array) $whereArrayAnd)
  385                     ) :
  386                     sprintf(
  387                         ' WHERE %s',
  388                         implode(" $whereOperator ", (array) $whereArrayAnd)
  389                     )
  390                 ) :
  391                 ''
  392             ),
  393             $groupBy,
  394             $orderBy
  395         );
  396         $data = [];
  397         self::$DB->query(
  398             $query,
  399             array(),
  400             $findVals
  401         )->fetch(
  402             '',
  403             'fetch_all'
  404         );
  405         if ($idField) {
  406             $data = (array)self::$DB->get($idField);
  407             if ($filter) {
  408                 return @$filter($data);
  409             }
  410             if (count($data) === 1) {
  411                 $data = array_shift($data);
  412             }
  413         } else {
  414             foreach ((array)self::$DB->get() as &$val) {
  415                 $data[] = new $this->childClass($val);
  416                 unset($val);
  417             }
  418         }
  419         if ($filter) {
  420             return @$filter($data);
  421         }
  422         return $data;
  423     }
  424     /**
  425      * Returns the count of items.
  426      *
  427      * @param array  $findWhere     what to find and count
  428      * @param string $whereOperator how to scan for where multiples
  429      * @param string $compare       how to compare items
  430      *
  431      * @return int
  432      */
  433     public function count(
  434         $findWhere = array(),
  435         $whereOperator = 'AND',
  436         $compare = '='
  437     ) {
  438         if (empty($findWhere)) {
  439             $findWhere = array();
  440         }
  441         if (empty($whereOperator)) {
  442             $whereOperator = 'AND';
  443         }
  444         if (empty($compare)) {
  445             $compare = '=';
  446         }
  447         $whereArray = array();
  448         $countVals = $countKeys = array();
  449         if (count($findWhere)) {
  450             foreach ((array) $findWhere as $field => &$value) {
  451                 $field = trim($field);
  452                 if (is_array($value) && count($value) > 0) {
  453                     foreach ((array) $value as $index => &$val) {
  454                         $key = sprintf(
  455                             '%s_%d',
  456                             $field,
  457                             $index
  458                         );
  459                         $countKeys[] = sprintf(':%s', $key);
  460                         $countVals[$key] = $val;
  461                         unset($val);
  462                     }
  463                     if (count($countKeys) > 0) {
  464                         $whereArray[] = sprintf(
  465                             '`%s` IN (%s)',
  466                             $this->databaseFields[$field],
  467                             implode(',', $countKeys)
  468                         );
  469                     }
  470                     unset($countKeys);
  471                 } else {
  472                     if (is_array($value)) {
  473                         $value = '';
  474                     }
  475                     $countVals[$field] = $value;
  476                     $whereArray[] = sprintf(
  477                         '`%s` %s :%s',
  478                         $this->databaseFields[$field],
  479                         (
  480                             preg_match(
  481                                 '#%#',
  482                                 $value
  483                             ) ?
  484                             'LIKE' :
  485                             trim($compare)
  486                         ),
  487                         $field
  488                     );
  489                 }
  490                 unset($value, $field);
  491             }
  492         }
  493         $knownEnable = array(
  494             'Image',
  495             'Snapin',
  496             'StorageNode',
  497         );
  498         $nonEnable = !(in_array($this->childClass, $knownEnable));
  499         $isEnabled = array_key_exists(
  500             'isEnabled',
  501             $this->databaseFields
  502         );
  503         if ($nonEnable && $isEnabled) {
  504             $isEnabled = sprintf(
  505                 '`%s`=1',
  506                 $this->databaseFields['isEnabled']
  507             );
  508         }
  509         $query = sprintf(
  510             $this->countQueryTemplate,
  511             $this->databaseTable,
  512             $this->databaseFields['id'],
  513             $this->databaseTable,
  514             (
  515                 count($whereArray) ?
  516                 sprintf(
  517                     ' WHERE %s%s',
  518                     implode(
  519                         sprintf(
  520                             ' %s ',
  521                             $whereOperator
  522                         ),
  523                         (array) $whereArray
  524                     ),
  525                     (
  526                         $isEnabled ?
  527                         sprintf(
  528                             ' AND %s',
  529                             $isEnabled
  530                         ) :
  531                         ''
  532                     )
  533                 ) :
  534                 (
  535                     $isEnabled ?
  536                     sprintf(
  537                         ' WHERE %s',
  538                         $isEnabled
  539                     ) :
  540                     ''
  541                 )
  542             )
  543         );
  544 
  545         return (int)self::$DB
  546             ->query($query, array(), $countVals)
  547             ->fetch()
  548             ->get('total');
  549     }
  550     /**
  551      * Inserts data in mass to the database.
  552      *
  553      * @param array $fields the fields to insert into
  554      * @param array $values the values to insert
  555      *
  556      * @return array
  557      */
  558     public function insertBatch($fields, $values)
  559     {
  560         $fieldlength = count($fields);
  561         $valuelength = count($values);
  562         if ($fieldlength < 1) {
  563             throw new Exception(_('No fields passed'));
  564         }
  565         if ($valuelength < 1) {
  566             throw new Exception(_('No values passed'));
  567         }
  568         $keys = array();
  569         foreach ((array) $fields as &$key) {
  570             $key = $this->databaseFields[$key];
  571             $keys[] = $key;
  572             $dups[] = sprintf(
  573                 '`%s`=VALUES(`%s`)',
  574                 $key,
  575                 $key
  576             );
  577             unset($key);
  578         }
  579         $vals = array();
  580         $insertVals = array();
  581         $values = array_chunk($values, 500);
  582         foreach ((array) $values as $ind => &$v) {
  583             foreach ((array) $v as $index => &$value) {
  584                 $insertKeys = array();
  585                 foreach ((array) $value as $i => &$val) {
  586                     $key = sprintf(
  587                         '%s_%d',
  588                         $fields[$i],
  589                         $index
  590                     );
  591                     $insertKeys[] = sprintf(
  592                         ':%s',
  593                         $key
  594                     );
  595                     $val = trim($val);
  596                     $insertVals[$key] = $val;
  597                     unset($val);
  598                 }
  599                 $vals[] = sprintf('(%s)', implode(',', (array) $insertKeys));
  600                 unset($value);
  601             }
  602             if (count($vals) < 1) {
  603                 throw new Exception(_('No data to insert'));
  604             }
  605             $query = sprintf(
  606                 $this->insertBatchTemplate,
  607                 $this->databaseTable,
  608                 implode('`,`', $keys),
  609                 implode(',', $vals),
  610                 implode(',', $dups)
  611             );
  612             self::$DB->query($query, array(), $insertVals);
  613             if ($ind === 0) {
  614                 $insertID = (int) self::$DB->insertId();
  615             }
  616             $affectedRows += (int) self::$DB->affectedRows();
  617             unset($v, $vals, $insertVals);
  618         }
  619         return array(
  620             $insertID,
  621             $affectedRows,
  622         );
  623     }
  624     /**
  625      * Function deals with enmass updating.
  626      *
  627      * @param array  $findWhere     what specific to update
  628      * @param string $whereOperator what to join where with
  629      * @param array  $insertData    the data to update
  630      *
  631      * @return bool
  632      */
  633     public function update(
  634         $findWhere = array(),
  635         $whereOperator = 'AND',
  636         $insertData = array()
  637     ) {
  638         if (empty($findWhere)) {
  639             $findWhere = array();
  640         }
  641         if (empty($whereOperator)) {
  642             $whereOperator = 'AND';
  643         }
  644         $insertArray = array();
  645         $whereArray = array();
  646         $updateVals = array();
  647         foreach ((array) $insertData as $field => &$value) {
  648             $field = trim($field);
  649             $value = trim($value);
  650             $updateKey = sprintf(
  651                 ':update_%s',
  652                 $field
  653             );
  654             $updateVals[sprintf('update_%s', $field)] = $value;
  655             $key = sprintf(
  656                 '`%s`.`%s`',
  657                 $this->databaseTable,
  658                 $this->databaseFields[$field]
  659             );
  660             $insertArray[] = sprintf(
  661                 '%s=%s',
  662                 $key,
  663                 $updateKey
  664             );
  665             unset($value);
  666         }
  667         unset($updateKey);
  668         $findVals = array();
  669         if (count($findWhere) > 0) {
  670             foreach ($findWhere as $field => &$value) {
  671                 $key = trim($field);
  672                 if (is_array($value) && count($value) > 0) {
  673                     foreach ($value as $i => &$val) {
  674                         $val = trim($val);
  675                         // Define the key
  676                         $k = sprintf(
  677                             '%s_%d',
  678                             $key,
  679                             $i
  680                         );
  681                         // Define param keys
  682                         $findKeys[] = sprintf(
  683                             ':%s',
  684                             $k
  685                         );
  686                         // Define the param array
  687                         $findVals[$k] = $val;
  688                         unset($val);
  689                     }
  690                     $whereArray[] = sprintf(
  691                         '`%s`.`%s` IN (%s)',
  692                         $this->databaseTable,
  693                         $this->databaseFields[$field],
  694                         implode(',', $findKeys)
  695                     );
  696                     unset($findKeys);
  697                 } else {
  698                     if (is_array($value)) {
  699                         $value = '';
  700                     }
  701                     $value = trim($value);
  702                     $k = sprintf(
  703                         '%s',
  704                         $key
  705                     );
  706                     // Define the param keys
  707                     $findKey = sprintf(
  708                         ':%s',
  709                         $key
  710                     );
  711                     // Define the param array
  712                     $findVals[$k] = $value;
  713                     $whereArray[] = sprintf(
  714                         '`%s`.`%s`%s%s',
  715                         $this->databaseTable,
  716                         $this->databaseFields[$field],
  717                         (
  718                             preg_match('#%#', (string) $value) ?
  719                             ' LIKE' :
  720                             '='
  721                         ),
  722                         $findKey
  723                     );
  724                 }
  725                 unset($value);
  726             }
  727         }
  728         unset($findKeys, $findKey);
  729         $query = sprintf(
  730             $this->updateQueryTemplate,
  731             $this->databaseTable,
  732             implode(',', (array) $insertArray),
  733             (
  734                 count($whereArray) ?
  735                 sprintf(
  736                     ' WHERE %s',
  737                     implode(" $whereOperator ", (array) $whereArray)
  738                 ) :
  739                 ''
  740             )
  741         );
  742         $queryVals = self::fastmerge(
  743             (array) $updateVals,
  744             (array) $findVals
  745         );
  746 
  747         return (bool) self::$DB->query($query, array(), $queryVals);
  748     }
  749     /**
  750      * Destroys items related to the main object.
  751      *
  752      * @param array  $findWhere     what to find
  753      * @param string $whereOperator how to combine where items
  754      * @param string $orderBy       how to order fields
  755      * @param string $sort          how the sort order
  756      * @param string $compare       how to compare
  757      * @param string $groupBy       how to group fields
  758      * @param bool   $not           use not operator
  759      *
  760      * @return bool
  761      */
  762     public function destroy(
  763         $findWhere = array(),
  764         $whereOperator = 'AND',
  765         $orderBy = 'name',
  766         $sort = 'ASC',
  767         $compare = '=',
  768         $groupBy = false,
  769         $not = false
  770     ) {
  771         // Fail safe defaults
  772         if (empty($findWhere)) {
  773             $findWhere = array();
  774         }
  775         if (empty($whereOperator)) {
  776             $whereOperator = 'AND';
  777         }
  778         if (empty($sort)) {
  779             $sort = 'ASC';
  780         }
  781         $this->orderBy($orderBy);
  782         if (empty($compare)) {
  783             $compare = '=';
  784         }
  785         $ids = $this->find(
  786             $findWhere,
  787             $whereOperator,
  788             $orderBy,
  789             $sort,
  790             $compare,
  791             $groupBy,
  792             $not,
  793             'id'
  794         );
  795         $destroyVals = array();
  796         $ids = array_chunk($ids, 500);
  797         foreach ((array)$ids as &$id) {
  798             foreach ((array) $id as $index => &$id_1) {
  799                 $keyStr = sprintf('id_%d', $index);
  800                 $destroyKeys[] = sprintf(':%s', $keyStr);
  801                 $destroyVals[$keyStr] = $id_1;
  802                 unset($id_1);
  803             }
  804             if (count($findWhere) > 0 && count($ids) < 1) {
  805                 return true;
  806             }
  807             $query = sprintf(
  808                 $this->destroyQueryTemplate,
  809                 $this->databaseTable,
  810                 $this->databaseTable,
  811                 $this->databaseFields['id'],
  812                 implode(',', (array) $destroyKeys)
  813             );
  814             unset($destroyKeys);
  815             self::$DB->query($query, array(), $destroyVals);
  816             unset($destroyVals, $destroyKeys);
  817         }
  818 
  819         return true;
  820     }
  821     /**
  822      * Builds a select box/option box from the elements.
  823      *
  824      * @param mixed  $matchID     select the matching id
  825      * @param string $elementName the name for the select box
  826      * @param string $orderBy     how to order
  827      * @param string $filter      should we filter existing
  828      * @param mixed  $template    should we include a template element
  829      *
  830      * @return string
  831      */
  832     public function buildSelectBox(
  833         $matchID = '',
  834         $elementName = '',
  835         $orderBy = 'name',
  836         $filter = '',
  837         $template = false
  838     ) {
  839         global $node;
  840         global $sub;
  841         if ($node === 'image' && $sub === 'add') {
  842             $waszero = false;
  843             if ($matchID === 0) {
  844                 $waszero = true;
  845                 $matchID = 9;  //default to Windows 10 (9)
  846             }
  847         }
  848         $elementName = trim($elementName);
  849         if (empty($elementName)) {
  850             $elementName = strtolower($this->childClass);
  851         }
  852         $this->orderBy($orderBy);
  853         ob_start();
  854         self::$HookManager
  855             ->processEvent(
  856                 'SELECT_BUILD',
  857                 array(
  858                     'matchID' => &$matchID,
  859                     'elementName' => &$elementName,
  860                     'orderBy' => &$orderBy,
  861                     'filter' => &$filter,
  862                     'template' => &$template,
  863                     'waszero' => &$waszero,
  864                     'obj' => $this
  865                 )
  866             );
  867         foreach ((array)$this
  868             ->find(
  869                 $filter ? array('id' => $filter) : '',
  870                 '',
  871                 $orderBy,
  872                 '',
  873                 '',
  874                 '',
  875                 ($filter ? true : false)
  876             ) as &$Object
  877         ) {
  878             if (!$Object->isValid()) {
  879                 continue;
  880             }
  881             if (array_key_exists('isEnabled', $this->databaseFields)
  882                 && !$Object->get('isEnabled')
  883             ) {
  884                 continue;
  885             }
  886             printf(
  887                 '<option value="%s"%s>%s</option>',
  888                 $Object->get('id'),
  889                 (
  890                     $matchID == $Object->get('id') ?
  891                     ' selected' :
  892                     (
  893                         $template ?
  894                         sprintf('${selected_item%d}', $Object->get('id')) :
  895                         ''
  896                     )
  897                 ),
  898                 sprintf(
  899                     '%s - (%d)',
  900                     $Object->get('name'),
  901                     $Object->get('id')
  902                 )
  903             );
  904             unset($Object);
  905         }
  906         $objOpts = ob_get_clean();
  907         $objOpts = trim($objOpts);
  908         if (empty($objOpts)) {
  909             return _('No items found');
  910         }
  911         $tmpStr .= '<select class="form-control input-group" name="'
  912             . (
  913                 $template ?
  914                 '${select_name}' :
  915                 $elementName
  916             )
  917             . '" id="'
  918             . $elementName
  919             . '" autocomplete="off">';
  920         $tmpStr .= '<option value="">- ';
  921         $tmpStr .= self::$foglang['PleaseSelect'];
  922         $tmpStr .= ' -</option>';
  923         $tmpStr .= $objOpts;
  924         $tmpStr .= '</select>';
  925         return $tmpStr;
  926     }
  927     /**
  928      * Checks if item already exists or not.
  929      *
  930      * @param string $val     the value to test
  931      * @param string $id      an ID if already exists
  932      * @param string $idField the id field to scan
  933      *
  934      * @return bool
  935      */
  936     public function exists(
  937         $val,
  938         $id = 0,
  939         $idField = 'name'
  940     ) {
  941         if (empty($id)) {
  942             $id = 0;
  943         }
  944         if (empty($idField)) {
  945             $idField = 'name';
  946         }
  947         $existVals = array(
  948             $idField => $val,
  949             'id' => $id,
  950         );
  951         $query = sprintf(
  952             $this->existsQueryTemplate,
  953             $this->databaseTable,
  954             $this->databaseFields[$idField],
  955             $this->databaseTable,
  956             $this->databaseTable,
  957             $this->databaseFields[$idField],
  958             sprintf(':%s', $idField),
  959             $this->databaseTable,
  960             $this->databaseFields[$idField],
  961             ':id'
  962         );
  963 
  964         return (bool)self::$DB
  965             ->query($query, array(), $existVals)
  966             ->fetch()
  967             ->get('total') > 0;
  968     }
  969     /**
  970      * Search for items passed to keyword.
  971      *
  972      * @param string $keyword       what to search for
  973      * @param bool   $returnObjects use ids or whole objects
  974      *
  975      * @return mixe
  976      */
  977     public function search($keyword = '', $returnObjects = false)
  978     {
  979         $keyword = trim($keyword);
  980         if (!$keyword) {
  981             $keyword = filter_input(INPUT_POST, 'crit');
  982         }
  983         if (!$keyword) {
  984             $keyword = filter_input(INPUT_GET, 'crit');
  985         }
  986         if (!$keyword) {
  987             throw new Exception(_('Nothing passed to search for'));
  988         }
  989         $mac_keyword = str_replace(
  990             array('-', ':'),
  991             '',
  992             $keyword
  993         );
  994         $mac_keyword = str_split($mac_keyword, 2);
  995         $mac_keyword = implode(':', $mac_keyword);
  996         $mac_keyword = preg_replace(
  997             '#[%\+\s\+]#',
  998             '%',
  999             sprintf(
 1000                 '%%%s%%',
 1001                 $mac_keyword
 1002             )
 1003         );
 1004         if (empty($keyword) || $keyword === '%') {
 1005             return $this->find();
 1006         }
 1007         $keyword = preg_replace(
 1008             '#[%\+\s\+]#',
 1009             '%',
 1010             sprintf(
 1011                 '%%%s%%',
 1012                 $keyword
 1013             )
 1014         );
 1015         if (count((array)$this->aliasedFields) > 0) {
 1016             self::arrayRemove($this->aliasedFields, $this->databaseFields);
 1017         }
 1018         $findWhere = array_fill_keys(array_keys($this->databaseFields), $keyword);
 1019         $find = array(
 1020             'name' => $keyword,
 1021             'description' => $keyword,
 1022         );
 1023         $itemIDs = self::getSubObjectIDs(
 1024             $this->childClass,
 1025             $findWhere,
 1026             'id',
 1027             '',
 1028             'OR'
 1029         );
 1030         $HostIDs = self::getSubObjectIDs(
 1031             'Host',
 1032             array(
 1033                 'name' => $keyword,
 1034                 'description' => $keyword,
 1035                 'ip' => $keyword,
 1036             ),
 1037             'id',
 1038             '',
 1039             'OR'
 1040         );
 1041         switch (strtolower($this->childClass)) {
 1042         case 'user':
 1043             break;
 1044         case 'host':
 1045             $macHostIDs = self::getSubObjectIDs(
 1046                 'MACAddressAssociation',
 1047                 array(
 1048                     'mac' => $mac_keyword,
 1049                     'description' => $keyword,
 1050                 ),
 1051                 'hostID',
 1052                 '',
 1053                 'OR'
 1054             );
 1055             $invHostIDs = self::getSubObjectIDs(
 1056                 'Inventory',
 1057                 array(
 1058                     'sysserial' => $keyword,
 1059                     'caseserial' => $keyword,
 1060                     'mbserial' => $keyword,
 1061                     'primaryUser' => $keyword,
 1062                     'other1' => $keyword,
 1063                     'other2' => $keyword,
 1064                     'sysman' => $keyword,
 1065                     'sysproduct' => $keyword,
 1066                 ),
 1067                 'hostID',
 1068                 '',
 1069                 'OR'
 1070             );
 1071             $HostIDs = self::fastmerge(
 1072                 $HostIDs,
 1073                 $macHostIDs,
 1074                 $invHostIDs
 1075             );
 1076             unset($invHostIDs, $macHostIDs);
 1077             $ImageIDs = self::getSubObjectIDs(
 1078                 'Image',
 1079                 $find,
 1080                 'id',
 1081                 '',
 1082                 'OR'
 1083             );
 1084             $GroupIDs = self::getSubObjectIDs(
 1085                 'Group',
 1086                 $find,
 1087                 'id',
 1088                 '',
 1089                 'OR'
 1090             );
 1091             $SnapinIDs = self::getSubObjectIDs(
 1092                 'Snapin',
 1093                 $find,
 1094                 'id',
 1095                 '',
 1096                 'OR'
 1097             );
 1098             $PrinterIDs = self::getSubObjectIDs(
 1099                 'Printer',
 1100                 $find,
 1101                 'id',
 1102                 '',
 1103                 'OR'
 1104             );
 1105             if (count($ImageIDs) > 0) {
 1106                 $itemIDs = self::fastmerge(
 1107                     $itemIDs,
 1108                     self::getSubObjectIDs(
 1109                         'Host',
 1110                         array('imageID' => $ImageIDs)
 1111                     )
 1112                 );
 1113             }
 1114             if (count($GroupIDs) > 0) {
 1115                 $itemIDs = self::fastmerge(
 1116                     $itemIDs,
 1117                     self::getSubObjectIDs(
 1118                         'GroupAssociation',
 1119                         array('groupID' => $GroupIDs),
 1120                         'hostID'
 1121                     )
 1122                 );
 1123             }
 1124             if (count($SnapinIDs) > 0) {
 1125                 $itemIDs = self::fastmerge(
 1126                     $itemIDs,
 1127                     self::getSubObjectIDs(
 1128                         'SnapinAssociation',
 1129                         array('snapinID' => $SnapinIDs),
 1130                         'hostID'
 1131                     )
 1132                 );
 1133             }
 1134             if (count($PrinterIDs) > 0) {
 1135                 $itemIDs = self::fastmerge(
 1136                     $itemIDs,
 1137                     self::getSubObjectIDs(
 1138                         'PrinterAssociation',
 1139                         array('printerID' => $PrinterIDs),
 1140                         'hostID'
 1141                     )
 1142                 );
 1143             }
 1144             $itemIDs = self::fastmerge($itemIDs, $HostIDs);
 1145             $itemIDs = array_filter($itemIDs);
 1146             $itemIDs = array_unique($itemIDs);
 1147             break;
 1148         case 'image':
 1149             if (count($HostIDs)) {
 1150                 $ImageIDs = self::getSubObjectIDs(
 1151                     'Host',
 1152                     array('id' => $HostIDs),
 1153                     'imageID'
 1154                 );
 1155                 $itemIDs = self::fastmerge($itemIDs, $ImageIDs);
 1156             }
 1157             $itemIDs = array_filter($itemIDs);
 1158             $itemIDs = array_unique($itemIDs);
 1159             break;
 1160         case 'task':
 1161             $TaskStateIDs = self::getSubObjectIDs(
 1162                 'TaskState',
 1163                 $find,
 1164                 'id',
 1165                 '',
 1166                 'OR'
 1167             );
 1168             $ImageIDs = self::getSubObjectIDs(
 1169                 'Image',
 1170                 $find,
 1171                 'id',
 1172                 '',
 1173                 'OR'
 1174             );
 1175             $GroupIDs = self::getSubObjectIDs(
 1176                 'Group',
 1177                 $find,
 1178                 'id',
 1179                 '',
 1180                 'OR'
 1181             );
 1182             $SnapinIDs = self::getSubObjectIDs(
 1183                 'Snapin',
 1184                 $find,
 1185                 'id',
 1186                 '',
 1187                 'OR'
 1188             );
 1189             $PrinterIDs = self::getSubObjectIDs(
 1190                 'Printer',
 1191                 $find,
 1192                 'id',
 1193                 '',
 1194                 'OR'
 1195             );
 1196             if (count($ImageIDs)) {
 1197                 $itemIDs = self::fastmerge(
 1198                     $itemIDs,
 1199                     self::getSubObjectIDs(
 1200                         'Host',
 1201                         array('imageID' => $ImageIDs)
 1202                     )
 1203                 );
 1204             }
 1205             if (count($GroupIDs)) {
 1206                 $itemIDs = self::fastmerge(
 1207                     $itemIDs,
 1208                     self::getSubObjectIDs(
 1209                         'GroupAssociation',
 1210                         array('groupID' => $GroupIDs),
 1211                         'hostID'
 1212                     )
 1213                 );
 1214             }
 1215             if (count($SnapinIDs)) {
 1216                 $itemIDs = self::fastmerge(
 1217                     $itemIDs,
 1218                     self::getSubObjectIDs(
 1219                         'SnapinAssociation',
 1220                         array('snapinID' => $SnapinIDs),
 1221                         'hostID'
 1222                     )
 1223                 );
 1224             }
 1225             if (count($PrinterIDs)) {
 1226                 $itemIDs = self::fastmerge(
 1227                     $itemIDs,
 1228                     self::getSubObjectIDs(
 1229                         'PrinterAssociation',
 1230                         array('printerID' => $PrinterIDs),
 1231                         'hostID'
 1232                     )
 1233                 );
 1234             }
 1235             if (count($TaskStateIDs)) {
 1236                 $itemIDs = self::fastmerge(
 1237                     $itemIDs,
 1238                     self::getSubObjectIDs(
 1239                         'Task',
 1240                         array('stateID' => $TaskStateIDs)
 1241                     )
 1242                 );
 1243             }
 1244             if (count($TaskTypeIDs)) {
 1245                 $itemIDs = self::fastmerge(
 1246                     $itemIDs,
 1247                     self::getSubObjectIDs(
 1248                         'Task',
 1249                         array('typeID' => $TaskTypeIDs)
 1250                     )
 1251                 );
 1252             }
 1253             if (count($HostIDs)) {
 1254                 $itemIDs = self::fastmerge(
 1255                     $itemIDs,
 1256                     self::getSubObjectIDs(
 1257                         'Task',
 1258                         array('hostID' => $HostIDs)
 1259                     )
 1260                 );
 1261             }
 1262             break;
 1263         default:
 1264             $assoc = sprintf(
 1265                 '%sAssociation',
 1266                 $this->childClass
 1267             );
 1268             $objID = sprintf(
 1269                 '%sID',
 1270                 strtolower($this->childClass)
 1271             );
 1272             if (!class_exists($assoc, false)) {
 1273                 break;
 1274             }
 1275             if (count($itemIDs) && !count($HostIDs)) {
 1276                 break;
 1277             }
 1278             $HostIDs = self::fastmerge(
 1279                 $HostIDs,
 1280                 self::getSubObjectIDs(
 1281                     $assoc,
 1282                     array($objID => $itemIDs),
 1283                     'hostID'
 1284                 )
 1285             );
 1286             if (count($HostIDs)) {
 1287                 $itemIDs = self::fastmerge(
 1288                     $itemIDs,
 1289                     self::getSubObjectIDs(
 1290                         $assoc,
 1291                         array('hostID' => $HostIDs),
 1292                         $objID
 1293                     )
 1294                 );
 1295             }
 1296             break;
 1297         }
 1298         $itemIDs = array_filter($itemIDs);
 1299         $itemIDs = array_unique($itemIDs);
 1300         $itemIDs = self::getSubObjectIDs(
 1301             $this->childClass,
 1302             array('id' => $itemIDs)
 1303         );
 1304         if ($returnObjects) {
 1305             return $this->find(array('id' => $itemIDs));
 1306         }
 1307 
 1308         return $itemIDs;
 1309     }
 1310     /**
 1311      * Returns the distinct (all matching).
 1312      *
 1313      * @param string $field         the field to be distinct
 1314      * @param array  $findWhere     what to find
 1315      * @param string $whereOperator how to scan for where multiples
 1316      * @param string $compare       comparitor
 1317      *
 1318      * @return int
 1319      */
 1320     public function distinct(
 1321         $field = '',
 1322         $findWhere = array(),
 1323         $whereOperator = 'AND',
 1324         $compare = '='
 1325     ) {
 1326         if (empty($findWhere)) {
 1327             $findWhere = array();
 1328         }
 1329         if (empty($whereOperator)) {
 1330             $whereOperator = 'AND';
 1331         }
 1332         if (empty($compare)) {
 1333             $compare = '=';
 1334         }
 1335         $whereArray = array();
 1336         $countVals = $countKeys = array();
 1337         if (count($findWhere) > 0) {
 1338             array_walk(
 1339                 $findWhere,
 1340                 function (
 1341                     &$value,
 1342                     &$field
 1343                 ) use (
 1344                     &$whereArray,
 1345                     $compare,
 1346                     &$countVals,
 1347                     &$countKeys
 1348                 ) {
 1349                     $field = trim($field);
 1350                     if (is_array($value) && count($value) > 0) {
 1351                         foreach ((array) $value as $index => &$val) {
 1352                             $countKeys[] = sprintf(':countVal%d', $index);
 1353                             $countVals[sprintf('countVal%d', $index)] = $val;
 1354                             unset($val);
 1355                         }
 1356                         $whereArray[] = sprintf(
 1357                             '`%s`.`%s` IN (%s)',
 1358                             $this->databaseTable,
 1359                             $this->databaseFields[$field],
 1360                             implode(',', $countKeys)
 1361                         );
 1362                     } else {
 1363                         if (is_array($value)) {
 1364                             $value = '';
 1365                         }
 1366                         $countVals['countVal'] = $value;
 1367                         $whereArray[] = sprintf(
 1368                             '`%s`.`%s`%s:countVal',
 1369                             $this->databaseTable,
 1370                             $this->databaseFields[$field],
 1371                             (
 1372                                 preg_match(
 1373                                     '#%#',
 1374                                     $value
 1375                                 ) ?
 1376                                 ' LIKE' :
 1377                                 $compare
 1378                             )
 1379                         );
 1380                     }
 1381                     unset($value, $field);
 1382                 }
 1383             );
 1384         }
 1385         $query = sprintf(
 1386             $this->distinctTemplate,
 1387             $this->databaseTable,
 1388             $this->databaseFields[$field],
 1389             $this->databaseTable,
 1390             (
 1391                 count($whereArray) ?
 1392                 sprintf(
 1393                     ' WHERE %s%s',
 1394                     implode(
 1395                         sprintf(
 1396                             ' %s ',
 1397                             $whereOperator
 1398                         ),
 1399                         (array) $whereArray
 1400                     ),
 1401                     (
 1402                         $isEnabled ?
 1403                         sprintf(
 1404                             ' AND %s',
 1405                             $isEnabled
 1406                         ) :
 1407                         ''
 1408                     )
 1409                 ) :
 1410                 (
 1411                     $isEnabled ?
 1412                     sprintf(
 1413                         ' WHERE %s',
 1414                         $isEnabled
 1415                     ) :
 1416                     ''
 1417                 )
 1418             )
 1419         );
 1420 
 1421         return (int)self::$DB
 1422             ->query($query, array(), $countVals)
 1423             ->fetch()
 1424             ->get('total');
 1425     }
 1426     /**
 1427      * Uninstalls the table.
 1428      *
 1429      * @return bool
 1430      */
 1431     public function uninstall()
 1432     {
 1433         $sql = Schema::dropTable($this->tablename);
 1434         return self::$DB->query($sql);
 1435     }
 1436 }