Location: PHPKode > scripts > Bitwise Flags > flags.class.php
<?php
class Flags {
    private $_flagNames = array();
    private $_flagInts = array();
    
    private $listCount = 0;
    
    public function __construct() {
        $flags = func_get_args();
        $flagList = array();
        if(count($flags) > 0) {
            if(is_array($flags[0])) $flags = $flags[0];
            $count = count($flags);
            $piece = 31;
            if($count > $piece) {
                $i=0;
                $listCount = 0;
                while($i<$count) {
                    $flagList[] = array_slice($flags,$i,$piece);
                    $i += $piece;
                    $listCount++;
                }
            } else {
                $flagList[0] = $flags;
                $listCount = 1;
            }
            
            foreach($flagList as $i=>$subList) {
                $count = 0x01;
                $this->_flagInts[$i] = 0x00;
                foreach($subList as $j=>$flag) {
                    $this->_flagNames[$i][$flag] = $count;
                    $count = $count * 2;
                }
            }
            
            $this->listCount = $listCount;
        }
    }
    
    private function _invalidFlag($flag,$flagIDX) {
        return ($flagIDX === false || !array_key_exists($flagIDX,$this->_flagNames) || !array_key_exists($flag,$this->_flagNames[$flagIDX]));
    }
    private function _findFlag($flag) {
        foreach($this->_flagNames as $i=>$flagList) {
            if(array_key_exists($flag,$flagList)) return $i;
        }
        throw new Exception('Flag '.$flag.' does not exist.');
    }
    private function _isFlagSet($flag,$flagIDX) {
        
        if($this->_invalidFlag($flag,$flagIDX)) return false;
        
        $isset = $this->_flagInts[$flagIDX] & $this->_flagNames[$flagIDX][$flag];
        return ($isset == $this->_flagNames[$flagIDX][$flag] ? true : false);
    }
    private function _setFlag($flag,$on,$flagIDX) {
        $flag = strtolower($flag);
        $isset = $this->_isFlagSet($flag,$flagIDX);
        
        if($this->_invalidFlag($flag,$flagIDX)) return false;
        
        if($on == true && !$isset) {
            $this->_flagInts[$flagIDX] = $this->_flagInts[$flagIDX] | $this->_flagNames[$flagIDX][$flag];
        } else if($on == false && $isset) {
            $this->_flagInts[$flagIDX] = $this->_flagInts[$flagIDX] ^ $this->_flagNames[$flagIDX][$flag];
        }
    }
    private function _forceBool($val) {
        if(is_bool($val)) {
            return $val;
        } else if(is_string($val)) {
            if(
                strtolower($val) == 'on'
                ||
                strtolower($val) == 'true'
            ) return true;
            else return false;
        } else if(is_numeric($val)) {
            return (bool) $val;
        } else {
            throw new Exception('Set value not of expected type. Expected string|numeric|boolean. Recieved '.gettype($val));
        }
    }
    
    public function toggleFlag($flag) {
        $idx = strtolower($flag);
        $flagIDX = $this->_findFlag($flag);
        $set = !$this->_isFlagSet($flag,$flagIDX);
        $this->_setFlag($flag,$set,$flagIDX);
        return $set;
    }
    public function setFlag($flag,$on = true) {
        $flag = strtolower($flag);
        $on = $this->_forceBool($on);
        $flagIDX = $this->_findFlag($flag);
        $this->_setFlag($flag,$on,$flagIDX);
        return $on;
    }
    public function isFlagSet($flag) {
        $flag = strtolower($flag);
        $flagIDX = $this->_findFlag($flag);
        return $this->_isFlagSet($flag,$flagIDX);
    }
    public function __get($idx) {
        return $this->isFlagSet($idx);
    }
    public function __set($name, $value) {
        if(!is_bool($value) && !is_numeric($value)) {
            // invalid values...
            throw new Exception('Setting flag expected boolean value.');
        }
        $this->setFlag($name,(bool)$value);
    }
    public function __call($name,$args) {
        $this->toggleFlag($name);
    }
    
    // niceties
    public function __toString() {
        $str = '';
        $format = '%1$40b';
        for($i=count($this->_flagInts)-1,$l=0;$i>=$l;$i--) {
            $bits = trim(sprintf($format,$this->_flagInts[$i]));
            while(strlen($bits) < 31) {
                $bits = '0'.$bits;
            }
            $str .= $bits;
        }
        return $str;
    }
    public function getData() {
        return serialize($this->_flagInts);
    }
    public function setData($data) {
        $this->_flagInts = unserialize($data);
        while(count($this->_flagInts) < $this->listCount) {
            $this->_flagInts[] = 0x00;
        }
        while(count($this->_flagInts) > $this->listCount) {
            array_splice($this->_flagInts,count($this->_flagInts)-1,1);
        }
    }
}
?>
Return current item: Bitwise Flags