<?php
/**
 * Copyright 2005-2017 de Solis Soluções Livres Ltda.
 *
 * Este arquivo é parte do programa Gnuteca.
 *
 * O Gnuteca é um software de propriedade da SOLIS, sendo desenvolvido
 * e mantido exclusivamente por esta empresa.
 *
 * A licença de uso está disponível mediante aquisição exclusiva junto à
 * SOLIS. A licença é concedida sem caráter de exclusividade ao licenciado.
 * Os direitos de uso são perpétuos.
 *
 * Embora os códigos fontes sejam fornecidos, o software é de propriedade
 * da SOLIS, não sendo permitido ao adquirente da licença a sua revenda,
 * empréstimo ou cessão (onerosa ou não) à terceiros. Também não é permitido,
 * a qualquer título e tempo, promover no software qualquer tipo de alienação,
 * reprodução, distribuição, divulgação, registro, licenciamento, transferência
 * ou qualquer outro ato que prejudique ou comprometa os direitos de propriedade
 * de software, o nome e a imagem da sua proprietária e do próprio software,
 * além de configurar concorrência à SOLIS.
 *
 * O licenciado, com o acesso ao código fonte do software, terá o direito de
 * promover mudanças no respectivo código. No entanto, nas situações em que ele
 * contar com o suporte oficial prestado pela SOLIS, não poderá promover mudanças
 * no código fonte, sob pena de perda do referido suporte.
 *
 * Para conhecer em detalhes o Termo de Licenciamento do Software Gnuteca
 * leia o arquivo “LICENCA.txt” disponível junto ao código deste software.
 * 
 * 
 * Gnuteca Web Services
 *
 *
 *
 *
 *
 **/


class GWebServices
{
    /**
     * Attributes
     */

    public      $MIOLO,
                $module;

    public      $busSoapAccess;

    protected   $clientId,
                $clientPassword,
                $clientIP,
                $authenticate;

    private     $className,
                $methodRequest,
                $webServiceObject,
                $clientObject,
                $errorCode;

    const WEB_SERVICES_OPERATOR         = "webServicesOperator";
    const ERROR_UNDEFINED_METHOD        = 1;
    const ERROR_UNDEFINED_PASS_ID       = 2;
    const ERROR_AUTHENTICATION_FAIL     = 3;
    const ERROR_DENIED_IP               = 4;
    const ERROR_SERVICE_UNAVALIABLE     = 5;
    const ERROR_ACCESS_BLOCKED          = 6;

    /**
     * Class constructor
     */
    public function __construct()
    {
        $this->className        = get_class($this);
        $this->clientIP         = GServer::getRemoteAddress();
        
        $this->authenticate     = false;
        $this->clientObject     = false;

        // INICIA ELEMENTOS DO MIOLO
        $this->MIOLO            = MIOLO::getInstance();
        $this->module           = $this->MIOLO->getCurrentModule();

        $this->MIOLO            ->getClass($this->module, "GBusiness");
        $this->MIOLO            ->getClass($this->module, "GXML");
        $this->busSoapAccess    = $this->MIOLO->getBusiness($this->module, 'BusSoapAccess');

        // INICIA UMA SESSÂO PARA PERCISTENCIA
        //$this->startSession();
    }


    /**
     * Seta os attributos do cliente.
     *
     * @param integer   $clientId
     * @param string    $clientPassword
     */
    public function __setClient($clientId, $clientPassword)
    {
        $this->clientId         = $clientId;
        $this->clientPassword   = $clientPassword;
    }
    
    /**
     *  Defone o nome da classe.
     * 
     * @param string $className
     */
    public function setClassName($className)
    {
        $this->className = $className;
    }

    /**
     * Seta o method que sera acessado
     *
     * @param string $methodName
     */
    protected function __setMethodRequest($methodName)
    {
        $this->methodRequest    = $methodName;
    }


    /**
     * checa permissão ao methodo
     *
     * @param string $method
     * @param boolean $die
     * @return boolean
     */
    public function __checkMethod($method, $die = true)
    {        
        $this->__setMethodRequest($method);

        if(!$this->__getWebService())
        {
            return $this->__die($die);
        }

        if($this->webServiceObject->needAuthentication != 'f')
        {
            if(!$this->__authenticate())
            {
                return $this->__die($die);
            }
        }

        if($this->webServiceObject->checkClientIp != 'f')
        {
            $this->__getClient();
            if($this->clientObject->ip != $this->clientIP)
            {
                $this->errorCode = self::ERROR_DENIED_IP;
                return $this->__die($die);
            }
        }
        
        if($this->webServiceObject->needAuthentication != 'f')
        {
            $this->__getClient();
            if(!$this->busSoapAccess->checkAccess($this->webServiceObject->webServiceId ,$this->clientObject->soapClientId))
            {
                $this->errorCode = self::ERROR_ACCESS_BLOCKED;
                return $this->__die($die);
            }
        }

        return true;
    }




    /**
     * Função que autentica um cliente
     *
     * @return boolean
     */
    private function __authenticate()
    {
        if(!strlen($this->clientId) || !strlen($this->clientPassword))
        {
            $this->errorCode = self::ERROR_UNDEFINED_PASS_ID;
            return $this->__die(false);
        }

        if($this->authenticate)
        {
            return true;
        }

        if($this->authenticate = $this->busSoapAccess->authenticate($this->clientId, $this->clientPassword))
        {
            return $this->authenticate;
        }

        $this->errorCode = self::ERROR_AUTHENTICATION_FAIL;
        return $this->__die(false);
    }


    /**
     * Retorna o web service cadastrado na base
     *
     * @return object
     */
    protected function __getWebService($returnType = "object")
    {
        $this->webServiceObject = null;
        if(!strlen($this->methodRequest))
        {
            $this->errorCode = self::ERROR_UNDEFINED_METHOD;
            return $this->__die(false);
        }

        $this->webServiceObject = $this->busSoapAccess->getWebServiceByClassAndMethod($this->className, $this->methodRequest);

        if(!$this->webServiceObject)
        {
            $this->errorCode = self::ERROR_SERVICE_UNAVALIABLE;
            return false;
        }

        switch ($returnType)
        {
            case "xml"      :
                $phpXML = new GXML($this->webServiceObject, "phpToXml");
                return $phpXML->getResult();
            case "object"   :
            default         : return $this->webServiceObject;
        }
    }


    /**
     * Retorna o web service cadastrado na base
     *
     * @return object
     */
    protected function __getClient()
    {
        $this->clientObject = null;
        if(!strlen($this->clientId))
        {
            $this->errorCode = ERROR_UNDEFINED_PASS_ID;
            return $this->__die(false);
        }

        $this->clientObject = $this->busSoapAccess->getClient($this->clientId);
        
        return $this->clientObject;
    }


    /**
     * retorna o operador de web services
     *
     * @return string
     */
    protected function getOperator()
    {
        $operator = !is_null($this->clientId) ? self::WEB_SERVICES_OPERATOR . "_Id[{$this->clientId}]" : self::WEB_SERVICES_OPERATOR;
        return $operator;
    }


    /**
     * função die
     *
     * @param booelan $die
     * @return die or false
     */
    private function __die($die = true)
    {
        if($die)
        {
            die();
        }

        return false;
    }


    /**
     * Retorna o codigo do erro
     *
     * @return integer
     */
    protected function __getError()
    {
        return $this->errorCode;
    }


    /**
     * Retorna a descriçao do erro
     *
     * @return string
     */
    public function __getErrorStr()
    {
        switch ($this->__getError())
        {
            case self::ERROR_UNDEFINED_METHOD:      return "[INTERNAL ERROR] 1 - methodRequest is not defined";
            case self::ERROR_UNDEFINED_PASS_ID:     return "[GLOBAL ERROR] 2 - clientId or clientPassword is not defined";
            case self::ERROR_AUTHENTICATION_FAIL:   return "[GLOBAL ERROR] 3 - Authetication fail";
            case self::ERROR_DENIED_IP:             return "[GLOBAL ERROR] 4 - IP not allowed. Your IP Address: $this->clientIP;";
            case self::ERROR_SERVICE_UNAVALIABLE:   return "[GLOBAL ERROR] 5 - Service not available.";
            case self::ERROR_ACCESS_BLOCKED:        return "[GLOBAL ERROR] 6 - You do not have access to this service.";
            default: return "[GLOBAL ERROR] Mensage not defined. Error Code: {$this->errorCode}";
        }
    }



    /**
     * trabalha o conteudo de acordo com o tipo de retorno desejado.
     *
     * @param object array $content
     * @param string $type
     * @return object | string xml
     */
    protected function returnType($content, $type = "xml", $encoding = "UTF-8")
    {
        switch(strtoupper($type))
        {
            case "PHP_OBJECT" :
                return $content;

            case "XML"  :
            default     :
                $xml = new GXML($content, "phpToXml", $encoding);
                return $xml->getResult();
        }
    }

    /**
     * Incia um sessão para percistencia do objeto
     *
     * Esta função não sera utilizada no momento, pois o miolo esta comprometendo a persistencia do soap do php
     *
     *
    private function startSession()
    {
        session_name($this->className);
        $this->sessionId = $_COOKIE[$this->className];

        if ($this->sessionId)
        {
            session_id($this->sessionId);
        }

        $this->sessionId = session_id();
        session_start();
    }
    */

}// final da classe

?>