Location: PHPKode > projects > Sierra-php PHP Application Framework > sierra/lib/model/SRA_WSGateway.php
<?php
// {{{ Header
/*
 +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~+
 | SIERRA : PHP Application Framework  http://code.google.com/p/sierra-php |
 +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~+
 | Copyright 2005 Jason Read                                               |
 |                                                                         |
 | Licensed under the Apache License, Version 2.0 (the "License");         |
 | you may not use this file except in compliance with the License.        |
 | You may obtain a copy of the License at                                 |
 |                                                                         |
 |     http://www.apache.org/licenses/LICENSE-2.0                          |
 |                                                                         |
 | Unless required by applicable law or agreed to in writing, software     |
 | distributed under the License is distributed on an "AS IS" BASIS,       |
 | WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.|
 | See the License for the specific language governing permissions and     |
 | limitations under the License.                                          |
 +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~+
 */
// }}}

// {{{ Imports
require_once('SRA_WSRequest.php');
require_once('SRA_WS.php');
require_once('SRA_WSGlobal.php');
// }}}

// {{{ Constants
/**
 * the identifier for the api doc type
 * @type string
 */
define('SRA_WS_GATEWAY_DOC_TYPE_API', 'api');

/**
 * the identifier for the entity doc type
 * @type string
 */
define('SRA_WS_GATEWAY_DOC_TYPE_ENTITY', 'entity');

/**
 * the identifier for the wsdl doc type
 * @type string
 */
define('SRA_WS_GATEWAY_DOC_TYPE_WSDL', 'wsdl');

/**
 * the identifier for the api css uri in the mapping file
 * @type string
 */
define('SRA_WS_GATEWAY_KEY_API_CSS_URI', '.api-css-uri');

/**
 * the identifier for the gateway rewrite flag in the mapping file
 * @type string
 */
define('SRA_WS_GATEWAY_KEY_REWRITE', '.gateway-rewrite');

/**
 * the identifier for the skip app id flag in the mapping file
 * @type string
 */
define('SRA_WS_GATEWAY_KEY_SKIP_APP_ID', '.gateway-skip-app-id');

/**
 * the identifier for the gateway uri in the mapping file
 * @type string
 */
define('SRA_WS_GATEWAY_KEY_URI', '.gateway-uri');

/**
 * the timeout threshold in minutes for an async request. when this threshold is 
 * reached and an invocation is made to retrieve the results of that request the 
 * status code SRA_WS_REQUEST_STATUS_TIMEOUT will be returned
 * @type int
 */
define('SRA_WS_GATEWAY_ASYNC_REQUEST_TIMEOUT', 5);

/**
 * the prefix to use for silent buffer session variables and file names
 * @type string
 */
define('SRA_WS_GATEWAY_BUFFER_PREFIX', '.wsBuffer');

/**
 * the number of minutes to keep an output buffer file
 * @type int
 */
define('SRA_WS_GATEWAY_BUFFER_FILE_REMOVE', 1);

/**
 * the prefix of the name of the temp file containing the service mappings. this 
 * file name will be followed by the app identifier
 * @type string
 */
define('SRA_WS_GATEWAY_MAPPING_FILE', '.ws-');

/**
 * the name of the no-op web service. this is a generic service that can be used 
 * to validate login credentials and start sessions
 * @type string
 */
define('SRA_WS_GATEWAY_NOOP', 'wsnoop');

/**
 * identifier for soap version 1.1
 * @type string
 */
define('SRA_WS_VERSION_1_1', '11');

/**
 * identifier for soap version 1.2
 * @type string
 */
define('SRA_WS_VERSION_1_2', '12');
// }}}

// {{{ SRA_WSGateway
/**
 * 
 * @author  Jason Read <hide@address.com>
 * @package sierra.model
 */
class SRA_WSGateway {
  /**
   * if the request is for api or wsdl documentation, this attribute will 
   * represent which
   * @type string
   */
  var $_doc;
  
  /**
   * TRUE if the request is soap
   * @type boolean
   */
  var $_isSoap = FALSE;
  
  /**
   * represents the request this gateway instance has been instantiated for
   * @type SRA_WSRequest
   */
  var $_request;
  
  /**
   * the service instance for this request
   * @type SRA_WS
   */
  var $_service;
  
  /**
   * the session variable for this request
   * @type string
   */
  var $_sessionVar;
  
	// {{{ SRA_WSGateway
	/**
	 * instantiates a new SRA_WSGateway instance to hande a web service request
   * @param hash $params the request parameters. these are documented in 
   * sra-ws-gateway.php
   * @access public
	 */
	function SRA_WSGateway(&$params) {
    require_once('SRA_WSRequest.php');
    $this->_bindDynamicParams($params);
    
    // php 5.2.2 bug workaround ($GLOBALS['HTTP_RAW_POST_DATA'] is not set)
    if (!isset($GLOBALS['HTTP_RAW_POST_DATA'])) { $GLOBALS['HTTP_RAW_POST_DATA'] = file_get_contents('php://input'); }
    
    // soap request
    if (isset($GLOBALS['HTTP_RAW_POST_DATA']) && preg_match('/xmlns:(.*)="(.*)envelope/', $GLOBALS['HTTP_RAW_POST_DATA'], $m)) {
      //sra_error::logerror($GLOBALS['HTTP_RAW_POST_DATA']);
      $soapKey = $m[1];
      $this->_isSoap = TRUE;
      $parser =& SRA_XmlParser::getXmlParser($GLOBALS['HTTP_RAW_POST_DATA'], TRUE);
      $data =& $parser->getData();
      if (isset($data[$soapKey . ':envelope'][$soapKey . ':body']) && 
          ($keys = array_keys($data[$soapKey . ':envelope'][$soapKey . ':body'])) && 
          ($keys1 = array_keys($data[$soapKey . ':envelope'][$soapKey . ':body'][$keys[0]])) && 
          ($keys2 = array_keys($data[$soapKey . ':envelope'][$soapKey . ':body'][$keys[0]][$keys1[1]])) && 
          isset($data[$soapKey . ':envelope'][$soapKey . ':body'][$keys[0]][$keys1[1]][$keys2[0]]['request']) && 
          ($keys3 = array_keys($data[$soapKey . ':envelope'][$soapKey . ':body'][$keys[0]][$keys1[1]][$keys2[0]]['request'])) && 
          isset($data[$soapKey . ':envelope'][$soapKey . ':body'][$keys[0]][$keys1[1]][$keys2[0]]['request'][$keys3[0]])) {
        $params['ws'] = preg_match('/.*:(.*)/', $keys1[1], $m) ? $m[1] : $keys1[1];
        $xmlConf = $data[$soapKey . ':envelope'][$soapKey . ':body'][$keys[0]][$keys1[1]][$keys2[0]]['request'][$keys3[0]];
        $params['ws-format'] = isset($xmlConf['attributes']['format']) ? $xmlConf['attributes']['format'] : SRA_WS_META_FORMAT_XML;
        $xmlConf = SRA_WSGateway::_convertSoapXml($xmlConf);
      }
    }
    else {
      $xmlConf = NULL;
    }
    
    if (isset($params['ws-request-xml'])) {
      if (!SRA_XmlParser::isValid($xmlParser =& SRA_XmlParser::getXmlParser($params['ws-request-xml'], TRUE))) {
        $msg = 'SRA_WSGateway: Failed - ws-request-xml count not be parsed: ' . $params['ws-request-xml'];
        $this->err = SRA_Error::logError($msg, __FILE__, __LINE__);
        return;
      }
      $xmlConf =& $xmlParser->getData();
    }
    $this->_request = new SRA_WSRequest($xmlConf, $this->_isSoap, isset($params['ws']) ? $params['ws'] : NULL);
    if (isset($params['ws-action'])) $this->_request->_action = $params['ws-action'];
    if (isset($params['ws-app'])) $this->_request->_app = $params['ws-app'];
    if (isset($params['ws-format'])) {
      $this->_request->_format = $params['ws-format'];
      $this->_request->_metaFormat = $this->_request->_format == SRA_WS_FORMAT_RAW ? SRA_WS_META_FORMAT_NONE : $this->_request->_format;
    }
    
    if (isset($params['ws-asynchronous'])) $this->_request->_asynchronous = SRA_Util::convertBoolean($params['ws-asynchronous']);
    $constraintGroups = array();
    foreach(array_keys($params) as $key) {
      if (preg_match('/ws-constraint(.*)-.*/', $key, $m) && count($m) == 2) {
        $constraintGroups[$m[1]] = array();
        foreach(array_keys($params) as $key) {
          if (preg_match('/ws-constraint' . $m[1] . '-attr(.*)/', $key, $m1) && count($m1) == 2) {
            $constraintGroups[$m[1]][] = $m1[1];
          }
        }
        if (!count($constraintGroups[$m[1]])) unset($constraintGroups[$m[1]]);
      }
    }
    foreach(array_keys($constraintGroups) as $gkey) {
      $gkeyPre = 'ws-constraint' . $gkey . '-';
      $gconf = array('attributes' => array(), 'ws-constraint' => array());
      if (isset($params[$gkeyPre . 'connective'])) $gconf['attributes']['connective'] = $params[$gkeyPre . 'connective'];
      foreach($constraintGroups[$gkey] as $ckey) {
        $cconf = array('attributes' => array());
        $cconf['attributes']['attr'] = $params[$gkeyPre . 'attr' . $ckey];
        if (isset($params[$gkeyPre . 'type' . $ckey])) $cconf['attributes']['attr-type'] = $params[$gkeyPre . 'type' . $ckey];
        if (isset($params[$gkeyPre . 'operator' . $ckey])) $cconf['attributes']['operator'] = $params[$gkeyPre . 'operator' . $ckey];
        if (isset($params[$gkeyPre . 'value' . $ckey])) $cconf['attributes']['value'] = $params[$gkeyPre . 'value' . $ckey];
        if (isset($params[$gkeyPre . 'value-type' . $ckey])) $cconf['attributes']['value-type'] = $params[$gkeyPre . 'value-type' . $ckey];
        $gconf['ws-constraint'][] = $cconf;
      }
      $this->_request->_constraintGroups[] = new SRA_WSConstraintGroup($gconf);
    }
    
    if (isset($params['ws-exclude'])) $this->_request->_excludeAttrs = explode(strpos($params['ws-exclude'], ',') ? ',' : ' ', $params['ws-exclude']);
    if (isset($params['ws-id'])) $this->_request->_primaryKey = $params['ws-id'];
    if (isset($params['ws-include'])) $this->_request->_includeAttrs = explode(strpos($params['ws-include'], ',') ? ',' : ' ', $params['ws-include']);
    if (isset($params['ws-js-dates'])) $this->_request->_jsDates = SRA_Util::convertBoolean($params['ws-js-dates']);
    if (isset($params['ws-date-format'])) $this->_request->_dateFormat = $params['ws-date-format'];
    if (isset($params['ws-time-format'])) $this->_request->_timeFormat = $params['ws-time-format'];
    if (isset($params['ws-date-format']) || isset($params['ws-time-format'])) $this->_request->_jsDates = FALSE;
    if (isset($params['ws-limit'])) $this->_request->_limit = $params['ws-limit'];
    if (isset($params['ws-meta-format'])) $this->_request->_metaFormat = $params['ws-meta-format'];
    if (isset($params['ws-offset'])) $this->_request->_offset = $params['ws-offset'];
    $rparams = array();
    foreach(array_keys($params) as $key) {
      if (preg_match('/ws-param(.*)/', $key, $m) && count($m) == 2 && !preg_match('/ws-param(.*)\-/', $key)) {
        $rparams[$m[1]] = TRUE;
      }
    }
    foreach(array_keys($rparams) as $pkey) {
      $pconf = array('attributes' => array('name' => $params['ws-param' . $pkey]));
      if (isset($params['ws-param' . $pkey . '-value'])) $pconf['attributes']['value'] = $params['ws-param' . $pkey . '-value'];
      if (isset($params['ws-param' . $pkey . '-value-type'])) $pconf['attributes']['value-type'] = $params['ws-param' . $pkey . '-value-type'];
      if (SRA_WSParam::isValid($param = new SRA_WSParam($pconf))) {
        if (isset($this->_request->_params[$param->_name])) {
          if (!is_array($this->_request->_params[$param->_name]->_value)) $this->_request->_params[$param->_name]->_value = array($this->_request->_params[$param->_name]->_value);
          $this->_request->_params[$param->_name]->_value[] = $param->_value;
        }
        else {
          $this->_request->_params[$param->_name] = $param;
        }
      }
    }
    if (isset($params['ws-password'])) $this->_request->_password = $params['ws-password'];
    if (isset($params['ws-query'])) $this->_request->_query = SRA_Util::convertBoolean($params['ws-query']);
    if (isset($params['ws-request-id'])) $this->_request->_requestId = $params['ws-request-id'];
    if (isset($params['ws-request-id1'])) $this->_request->_requestId1 = $params['ws-request-id1'];
    if (isset($params['ws-session-id'])) $this->_request->_sessionId = $params['ws-session-id'];
    if (isset($params['ws-use-sessions'])) $this->_request->_useSessions = SRA_Util::convertBoolean($params['ws-use-sessions']);
    if (isset($params['ws-user'])) $this->_request->_user = $params['ws-user'];
    if (isset($params['ws-validator'])) $this->_request->_validator = $params['ws-validator'];
    if ($this->_isSoap) $this->_request->_soapVersion = isset($params['ws-soap-version']) ? $params['ws-soap-version'] : SRA_WS_VERSION_1_2;
    if (isset($params['ws-wf-id'])) $this->_request->_workflowId = $params['ws-wf-id'];
    if (isset($params['ws-doc'])) $this->_doc = $params['ws-doc'];
    
    if (!isset($params['ws-request-xml'])) {
      foreach(array_keys($params) as $key) {
        if ($key == 'ws' || SRA_Util::beginsWith($key, 'ws-')) {
          unset($params[$key]);
        }
      }
      foreach(array_keys($params) as $key) {
        $pconf = array('attributes' => array('name' => $key, 'value' => $params[$key]));
        if (isset($params[$key . '-type'])) $pconf['attributes']['value-type'] = $params[$key . '-type'];
        if (SRA_WSParam::isValid($param = new SRA_WSParam($pconf))) {
          if (isset($this->_request->_params[$key])) {
            if (!is_array($this->_request->_params[$key]->_value)) $this->_request->_params[$key]->_value = array($this->_request->_params[$key]->_value);
            $this->_request->_params[$key]->_value[] = $param->_value;
          }
          else {
            $this->_request->_params[$key] = $param;
          }
        }
      }
    }
    
    $this->_sessionVar = SRA_WS_GATEWAY_BUFFER_PREFIX . $this->_request->_requestId . '_' . $this->_request->_requestId1;
    
    if ($this->_doc && $this->_doc != SRA_WS_GATEWAY_DOC_TYPE_API && $this->_doc != SRA_WS_GATEWAY_DOC_TYPE_ENTITY && $this->_doc != SRA_WS_GATEWAY_DOC_TYPE_WSDL) {
      $msg = 'SRA_WSGateway: Failed - ws-doc is not valid: ' . $this->_doc;
      $this->err = SRA_Error::logError($msg, __FILE__, __LINE__);
      return;
    }
    else if ($this->_request->__id != SRA_WS_GATEWAY_NOOP && $this->_request->_service && ((($this->_isSoap || $this->_doc == SRA_WS_GATEWAY_DOC_TYPE_WSDL) && !$this->_request->_service->_soap) || (!$this->_soap && !$this->_request->_service->_rest))) {
      $this->_request->_status = SRA_WS_REQUEST_STATUS_INVALID_PROTO;
    }
    
    if ($this->_isSoap) { $this->_request->_metaFormat = SRA_WS_META_FORMAT_XML; }
	}
	// }}}
  
	// {{{ printResponse
	/**
	 * renders the response from the web service request
   * @access public
   * @return void
	 */
	function printResponse() {
    if ($this->_request->_asynchronous) { ob_start(); }
    if ((!$this->_doc && $this->_request->_metaFormat == SRA_WS_META_FORMAT_XML) || $this->_doc == SRA_WS_GATEWAY_DOC_TYPE_WSDL) { 
      // determine correct mime type (soap 1.2 standard requires use of application/soap+xml mime type)
      $contentType = $this->_isSoap && $this->_request->_soapVersion == SRA_WS_VERSION_1_2 ? 'application/soap+xml' : 'text/xml';
      header('Content-Type: ' . $contentType);  
    }

    if ($this->_request->_query) {
      // delete old output buffer files
      $files = SRA_File::getFileList(SRA_Controller::getSysTmpDir(), '/^' . SRA_WS_GATEWAY_BUFFER_PREFIX . '.*$/');
      foreach($files as $key => $file) {
        if (time() > (filemtime($file) + (SRA_WS_GATEWAY_BUFFER_FILE_REMOVE * 60))) {
          SRA_File::unlink($file);
          unset($files[$key]);
        }
      }
      
      session_start();
      $outputBufferFile = SRA_Controller::getSysTmpDir() . '/' . $this->_sessionVar . '_' . session_id();
      if (!isset($_SESSION[$this->_sessionVar])) {
        $_SESSION[$this->_sessionVar] = time();
      }
      if (file_exists($outputBufferFile) || file_exists($outputBufferFile . '.cpl')) {
        echo SRA_File::toString($outputBufferFile . (file_exists($outputBufferFile) ? '' : '.cpl'));
        if (file_exists($outputBufferFile)) { SRA_File::move($outputBufferFile, $outputBufferFile . '.cpl'); }
        unset($_SESSION[$this->_sessionVar]);
        $skipPrint = TRUE;
      }
      else {
        if (time() > ($_SESSION[$this->_sessionVar] + (SRA_WS_GATEWAY_ASYNC_REQUEST_TIMEOUT * 60))) {
          $this->_request->_status = SRA_WS_REQUEST_STATUS_TIMEOUT;
          unset($_SESSION[$this->_sessionVar]);
          $msg = 'sra-ajax-gateway: Timeout occurred while waiting for request ' . $this->_request->_requestId . '/' . $this->_request->_requestId1;
          SRA_Error::logError($msg, __FILE__, __LINE__);
        }
        else {
          $this->_request->_status = SRA_WS_REQUEST_STATUS_RESULTS_NOT_AVAILABLE;
        }
      }
    }
    if (!$skipPrint && !$this->_doc) {
      $this->_request->printResponse();
    }
    else if ($this->_doc) {
      if ($this->_doc != SRA_WS_GATEWAY_DOC_TYPE_WSDL) {
        global $_wsGateway;
        $_wsGateway = NULL;
      }
      if (!SRA_Controller::init($this->_request->_app, $this->_doc == SRA_WS_GATEWAY_DOC_TYPE_WSDL, FALSE, TRUE, TRUE)) {
        $resources =& SRA_ResourceBundle::getBundle('web-services-api');
        echo $resources->getString('error.invalidApp');
        return FALSE;
      }
      if ($this->_doc != SRA_WS_GATEWAY_DOC_TYPE_WSDL) {
        $_wsGateway =& $this;
      }
      $tpl =& SRA_Controller::getSysTemplate();
      $tpl->assign('rewrite', SRA_WSGateway::isGatewayRewrite());
      $tpl->assign('skipAppId', SRA_WSGateway::isGatewaySkipAppId());
      
      // show wsdl
      if ($this->_doc == SRA_WS_GATEWAY_DOC_TYPE_WSDL) {
        if (!$this->_request->_id) {
          $services =& SRA_WSGateway::getServices();
        }
        else {
          $services = array();
          if ($this->_request->getService()) {
            $services[$this->_request->_id] =& $this->_request->getService();
          }
        }
        if (!$services) {
          $resources =& SRA_ResourceBundle::getBundle('web-services-api');
          echo $resources->getString('error.invalidService');
          return FALSE;
        }
        $tpl->assignByRef('services', $services);
        foreach(array_keys($services) as $key) {
          if ($services[$key]->_global) {
            $tpl->assign('hasGlobalService', TRUE);
            if ($services[$key]->_type == SRA_WS_GLOBAL_TYPE_RB) {
              $tpl->assign('hasRbService', TRUE);
            }
            else if ($services[$key]->_type == SRA_WS_GLOBAL_TYPE_SQL) {
              $tpl->assign('hasSqlService', TRUE);
            }
            else {
              $tpl->assign('hasMethodService', TRUE);
            }
          }
          else {
            $tpl->assign('hasEntityService', TRUE);
            if ($services[$key]->_create) { $tpl->assign('hasCreateService', TRUE); }
            if ($services[$key]->_delete) { $tpl->assign('hasDeleteService', TRUE); }
            if ($services[$key]->_retrieve) { $tpl->assign('hasRetrieveService', TRUE); }
            if ($services[$key]->_update) { $tpl->assign('hasUpdateService', TRUE); }
          }
          if (!$services[$key]->_formatFixed) {
            $tpl->assign('unfixedFormat', TRUE);
            if ($service[$key]->_global && $service[$key]->_type == SRA_WS_GLOBAL_TYPE_METHOD) {
              $tpl->assign('formatRaw', TRUE);
            }
            $tpl->assign('formatJson', TRUE);
            $tpl->assign('formatXml', TRUE);
          }
          if (!$services[$key]->_rest) {
            $tpl->assign('restRestricted', TRUE);
          }
          if (!$services[$key]->_soap) {
            $tpl->assign('soapRestricted', TRUE);
          }
        }
        
        $entities = array();
        if (!$this->_request->_id || (($service =& $this->_request->getService()) && !$service->_global)) {
          if ($this->_request->_id) {
            SRA_DaoFactory::getDao($service->_entity);
            $className = SRA_EntityModeler::getAppEntityClass($service->_entity);
            $types = array($service->_entity);
            eval('$types = array_merge($types, ' . $className . '::getAttributeTypesUsed(TRUE));');
            eval("\$hasNonMandatoryValidator = ${className}::hasNonMandatoryValidator();");
            $tpl->assign('hasNonMandatoryValidator', $hasNonMandatoryValidator);
          }
          else {
            $tpl->assign('hasNonMandatoryValidator', TRUE);
          }
          foreach(($this->_request->_id ? $types : SRA_EntityModeler::getAppEntityIds()) as $name) {
            require_once(SRA_EntityModeler::getAppEntityPath($name));
            $className = SRA_EntityModeler::getAppEntityClass($name);
            eval('$skipWsdl = ' . $className . '::skipWsdl();');
            
            if (!$skipWsdl) {
              if (!$usesFiles) { eval('$usesFiles = ' . $className . '::attributesUseFiles();'); }
              eval('$wsdl = ' . $className . '::getWsdl(NULL, NULL, "      ");');
              $entities[$className] = $wsdl;
            }
          }
        }
        $tpl->assign('usesFiles', $usesFiles);
        $tpl->assign('serviceSpecific', $this->_request->_id ? TRUE : FALSE);
        $tpl->assignByRef('entities', $entities);
        $tpl->display('model/sra-wsdl.tpl');
      }
      // show api documentation
      else {
        $tpl->assign('apiUri', SRA_WSGateway::getApiUri());
        $tpl->assign('authenticated', isset($_SERVER['PHP_AUTH_USER']));
        $tpl->assign('entityUri', SRA_WSGateway::getEntityUri());
        $tpl->assign('wsUri', SRA_Controller::getServerUri() . SRA_WSGateway::getGatewayUri());
        $tpl->assign('wsdlUri', SRA_WSGateway::getWsdlUri());
        $tpl->assignByRef('appResources', SRA_Controller::getAppResources());
        $tpl->assignByRef('apiResources', SRA_ResourceBundle::getBundle('web-services-api'));
        if ($wsCssUri = SRA_WSGateway::getService(SRA_WS_GATEWAY_KEY_API_CSS_URI)) { $tpl->assign('wsCssUri', $wsCssUri); }
        
        if ($this->_doc == SRA_WS_GATEWAY_DOC_TYPE_ENTITY) {
          if (!file_exists($entityPath = SRA_EntityModeler::getAppEntityPath($this->_request->_id))) {
            $msg = 'SRA_WSGateway: Failed - entity is not valid: ' . $this->_request->_id;
            $this->err = SRA_Error::logError($msg, __FILE__, __LINE__);
            return FALSE;
          }
          else {
            include_once($entityPath);
            $tmp = $this->_request->_id;
            $tpl->assignByRef('entity', new $tmp());
            $tpl->display('model/sra-ws-api-entity.tpl');
          }
        }
        else {
          if ($this->_request->_id && !SRA_WSGateway::getService($this->_request->_id)) {
            $resources =& SRA_ResourceBundle::getBundle('web-services-api');
            echo $resources->getString('error.invalidService');
            return FALSE;
          }
          
          // service specific api
          if ($this->_request->_id) {
            $tpl->assignByRef('service', $service =& SRA_WSGateway::getService($this->_request->_id));
            // assign api
            if ($service->_global && $service->_type == SRA_WS_GLOBAL_TYPE_METHOD && $service->_introspectApi && ($api =& SRA_Util::getStaticMethodPathApi($service->_identifier))) {
              $tpl->assignByRef('api', $api);
              $tpl->assign('usesLimit', isset($api['params']) && isset($api['params']['limit']));
              $tpl->assign('usesOffset', isset($api['params']) && isset($api['params']['offset']));
            }
            else if ($service->_global && $service->_type != SRA_WS_GLOBAL_TYPE_METHOD) {
              $tpl->assign('usesLimit', TRUE);
              $tpl->assign('usesOffset', TRUE);
            }
            // assign reference to dao and entity for entity specific services
            else if (!$service->_global && !SRA_Error::isError($dao =& SRA_DaoFactory::getDao($service->_entity))) {
              $tpl->assignByRef('dao', $dao);
              $tpl->assignByRef('entity', $dao->newInstance());
            }
            $tpl->display('model/sra-ws-api-service.tpl');
          }
          // services overview api
          else {
            $services =& SRA_WSGateway::getServices();
            $containsSoapService = FALSE;
            foreach(array_keys($services) as $key) {
              if ($services[$key]->_soap) {
                $containsSoapService = TRUE;
                break;
              }
            }
            $tpl->assign('containsSoapService', $containsSoapService);
            $tpl->assignByRef('services', $services);
            $tpl->display('model/sra-ws-api-overview.tpl');
          }
        }
      }
    }
    
    if ($this->_request->_asynchronous) {
      $_SESSION[$this->_sessionVar] = time();
      $outputBufferFile = SRA_Controller::getSysTmpDir() . '/' . $this->_sessionVar . '_' . session_id();
      $val = ob_get_contents();
      ob_end_clean();
      SRA_File::write($outputBufferFile . '.tmp', $val);
      SRA_File::move($outputBufferFile . '.tmp', $outputBufferFile);
    }
    
    if ($this->_request->_useSessions) { session_write_close(); }
	}
	// }}}
  
	// {{{ process
	/**
	 * processes the web service request. returns TRUE on success, FALSE if a 
   * system error occurs
   * @access public
   * @return boolean
	 */
	function process() {
    if (!$this->_doc && !$this->_request->_query) {
      return $this->_request->process();
    }
    else {
      return TRUE;
    }
	}
	// }}}
  
  
	// {{{ _bindDynamicParams
	/**
	 * binds any dynamic parameters in $params as documented in sra-ws-gateway.php 
   * and removes them from $params if they exist. invalid dynamic parameters 
   * will be logged and removed
   * @param hash $params the request parameters
   * @access private
   * @return void
	 */
	function _bindDynamicParams(&$params) {
    // dynamically binded parameters
    if (isset($params['ws1']) || isset($params['ws2']) || isset($params['ws3']) || isset($params['ws4']) || isset($params['ws5'])) {
      if (isset($params['ws1']) && !isset($params['ws-app']) && SRA_Controller::appKeyIsValid($params['ws1'])) {
        $params['ws-app'] = $params['ws1'];
      }
      else if (isset($params['ws1']) && !isset($params['ws-request-xml']) && strpos($params['ws1'], 'ws-request') !== FALSE) {
        $params['ws-request-xml'] = $params['ws1'];
      }
      else if (isset($params['ws1']) && $params['ws1']) {
        $msg = 'SRA_WSGateway::_bindDynamicParams: Warning - dynamic variable ws1 "' . $params['ws1'] . '" is not valid';
        SRA_Error::logError($msg, __FILE__, __LINE__);
      }
      if (isset($params['ws2']) && ($params['ws2'] == SRA_WS_VERSION_1_1 || $params['ws2'] == SRA_WS_VERSION_1_2)) {
        $params['ws-soap-version'] = $params['ws2'];
      }
      else if (isset($params['ws2']) && !isset($params['ws-doc']) && ($params['ws2'] == 'api' || $params['ws2'] == 'entity' || $params['ws2'] == 'wsdl')) {
        $params['ws-doc'] = $params['ws2'];
      }
      else if (isset($params['ws2']) && !isset($params['ws'])) {
        $params['ws'] = $params['ws2'];
      }
      else if (isset($params['ws2']) && $params['ws2']) {
        $msg = 'SRA_WSGateway::_bindDynamicParams: Warning - dynamic variable ws2 "' . $params['ws2'] . '" is not valid';
        SRA_Error::logError($msg, __FILE__, __LINE__);
      }
      if (isset($params['ws3']) && ($params['ws3'] == SRA_WS_VERSION_1_1 || $params['ws3'] == SRA_WS_VERSION_1_2)) {
        $params['ws-soap-version'] = $params['ws3'];
      }
      else if (isset($params['ws3']) && !isset($params['ws-doc']) && ($params['ws3'] == 'api' || $params['ws3'] == 'wsdl' || $params['ws3'] == 'entity')) {
        $params['ws-doc'] = $params['ws3'];
      }
      else if (isset($params['ws3']) && !isset($params['ws-format']) && ($params['ws3'] == 'json' || $params['ws3'] == 'xml' || $params['ws3'] == 'raw')) {
        $params['ws-format'] = $params['ws3'];
      }
      else if (isset($params['ws3']) && !isset($params['ws-action']) && ($params['ws3'] == 'create' || $params['ws3'] == 'delete' || $params['ws3'] == 'retrieve' || $params['ws3'] == 'update')) {
        $params['ws-action'] = $params['ws3'];
      }
      else if (isset($params['ws3']) && $params['ws3']) {
        $msg = 'SRA_WSGateway::_bindDynamicParams: Warning - dynamic variable ws3 "' . $params['ws3'] . '" is not valid';
        SRA_Error::logError($msg, __FILE__, __LINE__);
      }
      if (isset($params['ws4']) && ($params['ws4'] == SRA_WS_VERSION_1_1 || $params['ws4'] == SRA_WS_VERSION_1_2)) {
        $params['ws-soap-version'] = $params['ws4'];
      }
      else if (isset($params['ws4']) && !isset($params['ws-format']) && ($params['ws4'] == 'json' || $params['ws4'] == 'xml' || $params['ws4'] == 'raw')) {
        $params['ws-format'] = $params['ws4'];
      }
      else if (isset($params['ws4']) && !isset($params['ws-id'])) {
        $params['ws-id'] = $params['ws4'];
      }
      else if (isset($params['ws4']) && $params['ws4']) {
        $msg = 'SRA_WSGateway::_bindDynamicParams: Warning - dynamic variable ws4 "' . $params['ws4'] . '" is not valid';
        SRA_Error::logError($msg, __FILE__, __LINE__);
      }
      if (isset($params['ws5']) && ($params['ws5'] == SRA_WS_VERSION_1_1 || $params['ws5'] == SRA_WS_VERSION_1_2)) {
        $params['ws-soap-version'] = $params['ws5'];
      }
      else if (isset($params['ws5']) && !isset($params['ws-format']) && ($params['ws5'] == 'json' || $params['ws5'] == 'xml' || $params['ws5'] == 'raw')) {
        $params['ws-format'] = $params['ws5'];
      }
      else if (isset($params['ws5']) && $params['ws5']) {
        $msg = 'SRA_WSGateway::_bindDynamicParams: Warning - dynamic variable ws5 "' . $params['ws5'] . '" is not valid';
        SRA_Error::logError($msg, __FILE__, __LINE__);
      }
      unset($params['ws1']);
      unset($params['ws2']);
      unset($params['ws3']);
      unset($params['ws4']);
      unset($params['ws5']);
    }
	}
	// }}}
  
	
	// Static methods
  
  
	// {{{ cacheServices
	/**
	 * caches the serialized versions of the $services in a resources file indexed 
   * by service name. returns TRUE on success
	 * @param SRA_WS[] $services the services to cache
   * @param string $gatewayUri the uri to sra-ws-gateway.php
   * @param boolean $gatewayRewrite whether or not a rewrite rule is in place 
   * for $gatewayUri
   * @param boolean $gatewaySkipAppId whether or not to skip adding the app id 
   * when ws uris are generated (i.e. the app id is automatically added using 
   * a rewrite rule)
   * @param string $apiCssUri the uri to the css for web service api 
   * documentation
	 * @access public
	 * @return boolean
	 */
	function cacheServices(&$services, $gatewayUri, $gatewayRewrite=FALSE, $gatewaySkipAppId=FALSE, $apiCssUri=NULL) {
    static $_cached = array();
    // only cache web services once per instance per application
    if (!isset($_cached[$file = SRA_WSGateway::getAppMappingFile()])) {
      if ((file_exists($file) && !unlink($file)) || ($fp = fopen($file, 'w')) === FALSE) {
        $msg = "SRA_WSGateway::cacheServices: Failed - Unable to write to mappings file " . $file;
        SRA_Error::logError($msg, __FILE__, __LINE__);
        return FALSE;
      }
      foreach(array_keys($services) as $key) {
        fwrite($fp, $services[$key]->_id . '=' . serialize($services[$key]) . "\n");
      }
      fwrite($fp, SRA_WS_GATEWAY_KEY_URI . '=' . $gatewayUri . "\n");
      fwrite($fp, SRA_WS_GATEWAY_KEY_REWRITE . '=' . $gatewayRewrite . "\n");
      fwrite($fp, SRA_WS_GATEWAY_KEY_SKIP_APP_ID . '=' . $gatewaySkipAppId . "\n");
      fwrite($fp, SRA_WS_GATEWAY_KEY_API_CSS_URI . '=' . $apiCssUri);
      fclose($fp);
      chmod($file, 0666);
      $_cached[$file] = TRUE;
      return TRUE;
    }
    else {
      return FALSE;
    }
	}
	// }}}
  
	// {{{ getApiCssUri
	/**
	 * returns the gateway api css uri (if applicable) for the active application
	 * @access public
	 * @return string
	 */
	function getApiCssUri() {
    return SRA_WSGateway::getService(SRA_WS_GATEWAY_KEY_API_CSS_URI);
	}
	// }}}
  
	// {{{ getApiUri
	/**
	 * returns the api uri
	 * @access public
	 * @return string
	 */
	function getApiUri() {
		$wsUri = SRA_WSGateway::getService(SRA_WS_GATEWAY_KEY_URI);
    $wsUriRewrite = SRA_WSGateway::getService(SRA_WS_GATEWAY_KEY_REWRITE);
    $wsSkipAppId = SRA_WSGateway::getService(SRA_WS_GATEWAY_KEY_SKIP_APP_ID);
    return $wsUri . ($wsUriRewrite ? (!$wsSkipAppId ? '/' . SRA_Controller::getCurrentAppId() : '') . '/api' : (!$wsSkipAppId ? '?ws-app=' . SRA_Controller::getCurrentAppId() . '&' : '?') . 'ws-doc=api');
	}
	// }}}
  
	// {{{ getAppMappingFile
	/**
	 * returns the name of the current active application web services mapping 
   * file
	 *
	 * @access public
	 * @return string
	 */
	function getAppMappingFile() {
		return SRA_Controller::getAppTmpDir() . '/' . SRA_WS_GATEWAY_MAPPING_FILE . SRA_Controller::getCurrentAppId();
	}
	// }}}
  
	// {{{ getEntityUri
	/**
	 * returns the entity uri prefix
	 * @access public
	 * @return string
	 */
	function getEntityUri() {
		$wsUri = SRA_WSGateway::getService(SRA_WS_GATEWAY_KEY_URI);
    $wsUriRewrite = SRA_WSGateway::getService(SRA_WS_GATEWAY_KEY_REWRITE);
    $wsSkipAppId = SRA_WSGateway::getService(SRA_WS_GATEWAY_KEY_SKIP_APP_ID);
    return $wsUri . ($wsUriRewrite ? (!$wsSkipAppId ? '/' . SRA_Controller::getCurrentAppId() : '') . '/[entity]/entity' : (!$wsSkipAppId ? '?ws-app=' . SRA_Controller::getCurrentAppId() . '&' : '?') . 'ws-doc=entity&ws-id=[entity]');
	}
	// }}}
  
	// {{{ getGatewayUri
	/**
	 * returns the gateway uri for the active application
	 * @access public
	 * @return string
	 */
	function getGatewayUri() {
    return SRA_WSGateway::getService(SRA_WS_GATEWAY_KEY_URI);
	}
	// }}}
  
	// {{{ getService
	/**
	 * retrieves a reference to the service specified based on the current active 
   * platform or NULL if $id is not valid
	 * @param  string $id the identifier of the service to return
	 * @access public
	 * @return mixed
	 */
	function &getService($id) {
    static $services;
    $file = SRA_WSGateway::getAppMappingFile();
    if (!isset($services[$file])) {
      $services[$file] = array();
      $tmp = file($file);
      $keys = array_keys($tmp);
      foreach($keys as $key) {
        $pieces = explode('=', $tmp[$key], 2);
        $services[$file][$pieces[0]] = $pieces[0] != SRA_WS_GATEWAY_KEY_URI && $pieces[0] != SRA_WS_GATEWAY_KEY_REWRITE && $pieces[0] != SRA_WS_GATEWAY_KEY_SKIP_APP_ID && $pieces[0] != SRA_WS_GATEWAY_KEY_API_CSS_URI ? unserialize(str_replace("\n", "", $pieces[1])) : str_replace("\n", "", $pieces[1]);
      }
    }
    foreach(array_keys($services[$file]) as $service) {
      if (strtolower($id) == strtolower($service)) {
        return $services[$file][$service];
      }
    }
    return $nl = NULL;
	}
	// }}}
  
	// {{{ getServices
	/**
	 * returns a reference to an array of SRA_WS and/or SRA_WSGlobal instances 
   * representing the services defined for the current application
	 * @access public
	 * @return mixed
	 */
	function &getServices() {
    static $services;
    $file = SRA_WSGateway::getAppMappingFile();
    if (!isset($services[$file])) {
      $services[$file] = array();
      $tmp = file($file);
      $keys = array_keys($tmp);
      foreach($keys as $key) {
        $pieces = explode('=', $tmp[$key], 2);
        if ($pieces[0] == SRA_WS_GATEWAY_KEY_URI || $pieces[0] == SRA_WS_GATEWAY_KEY_REWRITE || $pieces[0] == SRA_WS_GATEWAY_KEY_SKIP_APP_ID || $pieces[0] == SRA_WS_GATEWAY_KEY_API_CSS_URI) { continue; }
        $services[$file][$pieces[0]] = $pieces[0] != SRA_WS_GATEWAY_KEY_URI ? unserialize(str_replace("\n", "", $pieces[1])) : str_replace("\n", "", $pieces[1]);
      }
    }
    return isset($services[$file]) ? $services[$file] :  ($nl = NULL);
	}
	// }}}
  
	// {{{ getServiceApiUri
	/**
	 * returns the api uri for $service
   * @param mixed $service the SRA_WS or SRA_WSGlobal to return the api uri for
	 * @access public
	 * @return string
	 */
	function getServiceApiUri(& $service) {
		$wsUri = SRA_WSGateway::getService(SRA_WS_GATEWAY_KEY_URI);
    $wsUriRewrite = SRA_WSGateway::getService(SRA_WS_GATEWAY_KEY_REWRITE);
    $wsSkipAppId = SRA_WSGateway::getService(SRA_WS_GATEWAY_KEY_SKIP_APP_ID);
    return $wsUri . ($wsUriRewrite ? (!$wsSkipAppId ? '/' . SRA_Controller::getCurrentAppId() : '') . '/' . $service->_id . '/api' : (!$wsSkipAppId ? '?ws-app=' . SRA_Controller::getCurrentAppId() . '&' : '?') . 'ws=' . $service->_id . '&ws-doc=api');
	}
	// }}}
  
	// {{{ getServiceWsdlUri
	/**
	 * returns the wsdl uri for $service
   * @param mixed $service the SRA_WS or SRA_WSGlobal to return the api uri for
	 * @access public
	 * @return string
	 */
	function getServiceWsdlUri(& $service) {
		$wsUri = SRA_WSGateway::getService(SRA_WS_GATEWAY_KEY_URI);
    $wsUriRewrite = SRA_WSGateway::getService(SRA_WS_GATEWAY_KEY_REWRITE);
    $wsSkipAppId = SRA_WSGateway::getService(SRA_WS_GATEWAY_KEY_SKIP_APP_ID);
    return $wsUri . ($wsUriRewrite ? (!$wsSkipAppId ? '/' . SRA_Controller::getCurrentAppId() : '') . '/' . $service->_id . '/wsdl' : (!$wsSkipAppId ? '?ws-app=' . SRA_Controller::getCurrentAppId() . '&' : '?') . 'ws=' . $service->_id . '&ws-doc=wsdl');
	}
	// }}}
  
	// {{{ getWsdlUri
	/**
	 * returns the wsdl uri
	 * @access public
	 * @return string
	 */
	function getWsdlUri() {
		$wsUri = SRA_WSGateway::getService(SRA_WS_GATEWAY_KEY_URI);
    $wsUriRewrite = SRA_WSGateway::getService(SRA_WS_GATEWAY_KEY_REWRITE);
    $wsSkipAppId = SRA_WSGateway::getService(SRA_WS_GATEWAY_KEY_SKIP_APP_ID);
    return $wsUri . ($wsUriRewrite ? (!$wsSkipAppId ? '/' . SRA_Controller::getCurrentAppId() : '') . '/wsdl' : (!$wsSkipAppId ? '?ws-app=' . SRA_Controller::getCurrentAppId() . '&' : '?') . 'ws-doc=wsdl');
	}
	// }}}
  
	// {{{ isGatewayRewrite
	/**
	 * returns TRUE if rewrite rule is in place for the gateway uri
	 * @access public
	 * @return boolean
	 */
	function isGatewayRewrite() {
    return SRA_WSGateway::getService(SRA_WS_GATEWAY_KEY_REWRITE) ? TRUE : FALSE;
	}
	// }}}
  
	// {{{ isGatewaySkipAppId
	/**
	 * returns TRUE if the app id should not be used in web service uris
	 * @access public
	 * @return boolean
	 */
	function isGatewaySkipAppId() {
    return SRA_WSGateway::getService(SRA_WS_GATEWAY_KEY_SKIP_APP_ID) ? TRUE : FALSE;
	}
	// }}}
	
	// {{{ isValid
	/**
	 * Sreturns true if the $object is a SRA_WSGateway instance
	 * @param object $object the object to validate
	 * @access public
	 * @return boolean
	 */
	function isValid(&$object) {
		return (is_object($object) && (!isset($object->err) || !SRA_Error::isError($object->err)) && strtolower(get_class($object)) == 'sra_wsgateway');
	}
	// }}}
  
	// {{{ _convertSoapXml
	/**
	 * converts a soap xml request so it is compliant with ws-request.dtd
	 * @access private
	 * @return array
	 */
	function _convertSoapXml($xml) {
    $converted = array();
    foreach(array_keys($xml) as $key) {
      $newKey = NULL;
      switch(strtolower($key)) {
        case 'attrtype':
          $newKey = 'attr-type';
          break;
        case 'valuetype':
          $newKey = 'value-type';
          break;
        case 'constraint':
          $newKey = 'ws-constraint';
          break;
        case 'param':
          $newKey = 'ws-param';
          break;
        case 'excludeattrs':
          $newKey = 'exclude-attrs';
          break;
        case 'includeattrs':
          $newKey = 'include-attrs';
          break;
        case 'jsDates':
          $newKey = 'ws-js-dates';
          break;
        case 'dateFormat':
          $newKey = 'ws-date-format';
          break;
        case 'timeFormat':
          $newKey = 'ws-time-format';
          break;
        case 'requestid':
          $newKey = 'request-id';
          break;
        case 'requestid1':
          $newKey = 'request-id1';
          break;
        case 'constraintgroup':
          $newKey = 'ws-constraint-group';
          break;
        case 'create':
          $newKey = 'ws-create';
          break;
        case 'delete':
          $newKey = 'ws-delete';
          break;
        case 'retrieve':
          $newKey = 'ws-retrieve';
          break;
        case 'sessionid':
          $newKey = 'session-id';
          break;
        case 'update':
          $newKey = 'ws-update';
          break;
        case 'usesessions':
          $newKey = 'use-sessions';
          break;
        case 'workflowid':
          $newKey = 'workflow-id';
          break;
      }
      
      if (is_array($xml[$key])) {
        $converted[$newKey ? $newKey : $key] = SRA_WSGateway::_convertSoapXml($xml[$key]);
      }
      else {
        $converted[$newKey ? $newKey : $key] = $xml[$key];
      }
    }
    return $converted;
	}
	// }}}
  
}
// }}}
?>
Return current item: Sierra-php PHP Application Framework