jackkum/PHPPDU

View on GitHub
PDU/SCA.php

Summary

Maintainability
B
5 hrs
Test Coverage
<?php

/* 
 * Copyright (C) 2014 jackkum
 *
 * This program is free software: you can redistribute it and/or modify
 * it under the terms of the GNU General Public License as published by
 * the Free Software Foundation, either version 3 of the License, or
 * (at your option) any later version.
 *
 * This program is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 * GNU General Public License for more details.
 *
 * You should have received a copy of the GNU General Public License
 * along with this program.  If not, see <http://www.gnu.org/licenses/>.
 */

namespace jackkum\PHPPDU\PDU;

use jackkum\PHPPDU\PDU;

class SCA {
    
    /**
     * Type of number
     * @var SCA\Type
     */
    protected $_type   = NULL;
    
    /**
     * Phone size
     * @var integer
     */
    protected $_size   = 0x00;
    
    
    /**
     * phone number
     * @var string
     */
    protected $_phone  = NULL;
    
    /**
     * recipient encoded
     * @var type 
     */
    protected $_encoded = NULL;


    /**
     * how claclulate size (octets or digits)
     * OA and DA size is on digits
     * @var boolean
     */
    protected $_isAddress = FALSE;
    
    /**
     * create object
     * @param boolean $isAddress 
     */
    public function __construct($isAddress = TRUE)
    {
        // create sca type
        $this->setType(new SCA\Type());
        
        $this->_isAddress = !!$isAddress;
    }
    
    public static function parse($isAddress = TRUE)
    {
        $SCA     = new self($isAddress);
        $size    = hexdec(PDU::getPduSubstr(2));
        
        if($size){
            
            // if is OA or DA size in digits
            if($isAddress){
                if(($size % 2) != 0){
                    $size++;
                }
            // else size in octets
            } else {
                $size--;
                $size *= 2;
            }
            
            $SCA->setType(
                new SCA\Type(
                    hexdec(PDU::getPduSubstr(2))
                )
            );
            
            $hex = PDU::getPduSubstr($size);
            
            switch($SCA->getType()->getType()){
                case SCA\Type::TYPE_UNKNOWN: 
                case SCA\Type::TYPE_INTERNATIONAL:
                case SCA\Type::TYPE_ACCEPTER_INTO_NET:
                case SCA\Type::TYPE_SUBSCRIBER_NET:
                case SCA\Type::TYPE_TRIMMED:
                    
                    $SCA->setPhone(
                        rtrim(
                            implode(
                                "",
                                array_map(
                                    'strrev', 
                                    array_map(
                                        array('self', '_map_filter_decode'),
                                        str_split($hex, 2)
                                    )
                                )
                            ),
                            'F'
                        )
                    );
                    
                    break;
                
                case SCA\Type::TYPE_ALPHANUMERICAL:
                    
                    $SCA->setPhone(
                        PDU\Helper::decode7bit($hex)
                    );
                    
                    break;
                
            }
            
        }
        
        return $SCA;
    }

    /**
     * getter for phone
     * @return string|null
     */
    public function getPhone()
    {
        return $this->_phone;
    }
    
    /**
     * set phone number
     * @param string $phone
     * @param boolean $SC 
     */
    public function setPhone($phone, $SC = FALSE)
    {
        $this->_phone     = $phone;
        $clear            = preg_replace('/([^a-c0-9\*\#]*)/', NULL, $phone);
        $this->_isAddress = !$SC;
        
        if($this->getType()->getType() == SCA\Type::TYPE_ALPHANUMERICAL){
            list($this->_size, $this->_encoded) = PDU\Helper::encode7bit($clear);
        } else {
            
            // get size
            // service center addres counting by octets OA or DA as length numbers
            $this->_size = $SC ? 1 + ((strlen($clear) + 1)/2) : strlen($clear);
            
            $this->_encoded = implode(
                "",
                array_map(                               // join filtered phone letters
                    array('self', '_map_filter_encode'), // encode filter
                    str_split($clear)
                )
            );
            
        }
        
    }
    
    /**
     * getter for phone size
     * @return integer
     */
    public function getSize()
    {
        return $this->_size;
    }
    
    /**
     * getter for phone type
     * @return SCA\Type
     */
    public function getType()
    {
        return $this->_type;
    }
    
    /**
     * setter type
     * @param SCA\Type $type
     */
    public function setType(SCA\Type $type)
    {
        $this->_type = $type;
    }
    
    /**
     * check is address
     * @return boolean
     */
    public function isAddress()
    {
        return !!$this->_isAddress;
    }
    
    /**
     * magic method for cast to string
     * @return srting|null
     */
    public function __toString()
    {
        $PDU = sprintf("%02X", $this->getSize());
        
        if($this->getSize()){
            
            $PDU .= $this->getType();

            if($this->getType()->getType() != SCA\Type::TYPE_ALPHANUMERICAL){
                // reverse octets
                $l = strlen($this->_encoded);
                for($i = 0; $i < $l; $i += 2){
                    $b1 = substr($this->_encoded, $i, 1);
                    $b2 = (($i + 1) >= $l) ? 'F' : substr($this->_encoded, $i+1, 1);
                    // add to pdu
                    $PDU .= $b2 . $b1;
                }
            }
        }
        
        PDU::debug("SCA::__toString() " . $PDU);
        
        return $PDU;
    }
    
    /**
     * get offset
     * @return integer
     */
    public function getOffset()
    {
        return ( ! $this->_size ? 2 : $this->_size + 4);
    }
    
    /**
     * decode phone number
     * @param string $letter
     * @return string
     */
    private static function _map_filter_decode($letter)
    {
        switch(hexdec($letter)){
            case 0x0A: return "*";
            case 0x0B: return "#";
            case 0x0C: return "a";
            case 0x0D: return "b";
            case 0x0E: return "c";
            default: return $letter;
        }
    }
    
    
    /**
     * encode phone number
     * @param string $letter
     * @return string
     */
    private static function _map_filter_encode($letter)
    {
        switch($letter){
            case "*": return 'A';
            case "#": return 'B';
            case "a": return 'C';
            case "b": return 'D';
            case "c": return 'E';
            default: return $letter;
        }
    }
    
}