/**
  * Method to transform a type to publish it in the WSDL file
  *
  * @param   array             $field             Field definition.
  * @param   SimpleXMLElement  &$sequence         XML with the fields sequence
  * @param   SimpleXMLElement  &$typeSchema       XML of the typeSchema in case new derived types need to be added
  * @param   string            $elementName       Parent element name to add the new derived types with unique names
  * @param   boolean           $validateOptional  Optional parameter to validate if the field is optional.  Otherwise it's always set as required
  * @param   array             $extraFields       Array of extra fields to process - in case of array types
  * @param   SimpleXMLElmenet  $complexArrays     Complex arrays definitions
  *
  * @return void
  */
 public function wsdlField($field, &$sequence, &$typeSchema, $elementName, $validateOptional = false, $extraFields = array(), $complexArrays = null)
 {
     parent::wsdlField($field, $sequence, $typeSchema, $elementName, $validateOptional);
     $this->element->addAttribute('type', 'tns:' . $elementName . '_' . $field['name']);
     if (!empty($extraFields)) {
         RApiSoapHelper::addElementFields($extraFields, $typeSchema, $elementName . '_' . $field['name'], false, '', $complexArrays);
     }
 }
Exemple #2
0
 /**
  * Method to transform a type to publish it in the WSDL file
  *
  * @param   array             $field             Field definition.
  * @param   SimpleXMLElement  &$sequence         XML with the fields sequence
  * @param   SimpleXMLElement  &$typeSchema       XML of the typeSchema in case new derived types need to be added
  * @param   string            $elementName       Parent element name to add the new derived types with unique names
  * @param   boolean           $validateOptional  Optional parameter to validate if the field is optional.  Otherwise it's always set as required
  * @param   array             $extraFields       Array of extra fields to process - in case of array types
  * @param   SimpleXMLElmenet  $complexArrays     Complex arrays definitions
  *
  * @return void
  */
 public function wsdlField($field, &$sequence, &$typeSchema, $elementName, $validateOptional = false, $extraFields = array(), $complexArrays = null)
 {
     if (!isset($this->element)) {
         $this->element = $sequence->addChild('element', null, 'http://www.w3.org/2001/XMLSchema');
     }
     if (!isset($this->element['minOccurs'])) {
         $this->element->addAttribute('minOccurs', $validateOptional && RApiHalHelper::isAttributeTrue($field, 'isRequiredField') || !$validateOptional ? '1' : '0');
     }
     $this->element->addAttribute('maxOccurs', 'unbounded');
     if (!isset($this->element['name']) && isset($field['name'])) {
         $this->element->addAttribute('name', $field['name']);
     }
     $this->element->addAttribute('type', 'tns:' . $elementName . '_' . $field['name']);
     if (!empty($extraFields)) {
         RApiSoapHelper::addElementFields($extraFields, $typeSchema, $elementName . '_' . $field['name'], true, '', $complexArrays);
     }
 }
Exemple #3
0
 /**
  * Method to send the application response to the client.  All headers will be sent prior to the main
  * application output data.
  *
  * @return  void
  *
  * @since   1.4
  */
 public function render()
 {
     $documentOptions = array('absoluteHrefs' => $this->options->get('absoluteHrefs', false), 'documentFormat' => 'xml');
     if ($this->operation == 'wsdl') {
         // Needed for formatting
         $dom = dom_import_simplexml($this->wsdl)->ownerDocument;
         $dom->preserveWhiteSpace = false;
         $dom->formatOutput = true;
         $body = $dom->saveXML();
     } else {
         // Add error faults if they exist
         if ($this->webservice->statusCode >= 300) {
             // We must have status of 200 for SOAP communication even if it is fault
             $this->setStatusCode(200);
             $faultResponse = $this->prepareFaultResponseMessage($this->webservice);
             $body = RApiSoapHelper::createSoapFaultResponse($faultResponse);
         } else {
             $body = $this->getBody();
         }
     }
     JFactory::$document = new RApiSoapDocumentDocument($documentOptions, $this->operation == 'wsdl' ? 'xml' : 'soap+xml');
     $body = $this->triggerFunction('prepareBody', $body);
     // Push results into the document.
     JFactory::$document->setApiObject($this)->setBuffer($body)->render(false);
 }
Exemple #4
0
 /**
  * Returns generated WSDL file for the webservice
  *
  * @param   string  $wsdlPath  Path of WSDL file
  *
  * @return  SimpleXMLElement
  */
 public function generateWsdl($wsdlPath)
 {
     $wsdlFullPath = JUri::root() . $wsdlPath;
     $client = RApiHalHelper::attributeToString($this->webserviceXml, 'client', 'site');
     $version = !empty($this->webserviceXml->config->version) ? $this->webserviceXml->config->version : '1.0.0';
     $this->webserviceFullName = $client . '.' . $this->webserviceXml->config->name . '.' . $version;
     $this->webserviceUrl = RApiHalHelper::buildWebserviceFullUrl($client, $this->webserviceXml->config->name, $version, 'soap');
     // Root of the document
     $this->wsdl = new SimpleXMLElement('<?xml version="1.0" encoding="utf-8" ?><wsdl:definitions' . ' xmlns:soapenc="http://schemas.xmlsoap.org/soap/encoding/"' . ' xmlns:mime="http://schemas.xmlsoap.org/wsdl/mime/"' . ' xmlns:tns="' . $wsdlFullPath . '"' . ' xmlns:soap="http://schemas.xmlsoap.org/wsdl/soap12/"' . ' xmlns:s="http://www.w3.org/2001/XMLSchema"' . ' xmlns:http="http://schemas.xmlsoap.org/wsdl/http/"' . ' targetNamespace="' . $wsdlFullPath . '"' . ' xmlns:wsdl="http://schemas.xmlsoap.org/wsdl/"' . ' ></wsdl:definitions>', 0, false, 'wsdl', true);
     $types = $this->wsdl->addChild('types');
     $this->typeSchema = $types->addChild('schema', null, 'http://www.w3.org/2001/XMLSchema');
     $this->typeSchema->addAttribute('targetNamespace', $wsdlFullPath);
     $this->typeSchema->addAttribute('elementFormDefault', 'unqualified');
     $this->addGlobalTypes($this->typeSchema);
     // Adding service
     $this->wsdlServices = $this->wsdl->addChild('service');
     $this->wsdlServices->addAttribute('name', $this->webserviceFullName);
     $this->wsdlServices->addChild('documentation', $this->webserviceXml->description);
     // Add new port binding
     $port = $this->wsdlServices->addChild('port');
     $port->addAttribute('name', $this->webserviceFullName . '_Soap');
     $port->addAttribute('binding', 'tns:' . $this->webserviceFullName);
     // Add soap addresses
     $soapAddress = $port->addChild('soap:address', null, 'http://schemas.xmlsoap.org/wsdl/soap12/');
     $soapAddress->addAttribute('location', $this->webserviceUrl);
     // Add webservice operations
     if (isset($this->webserviceXml->operations)) {
         // Read list
         if (isset($this->webserviceXml->operations->read->list)) {
             $filters = RApiHalHelper::getFilterFields($this->webserviceXml->operations->read->list, true, true);
             if (empty($filters)) {
                 $filtersDef = array('name' => 'filters', 'transform' => 'array');
             } else {
                 $filtersDef = array('name' => 'filters', 'transform' => 'arraydefined', 'fields' => $filters);
             }
             // Add read list messages
             $inputFields = array(array('name' => 'limitStart', 'transform' => 'int'), array('name' => 'limit', 'transform' => 'int'), array('name' => 'filterSearch', 'transform' => 'string'), $filtersDef, array('name' => 'ordering', 'transform' => 'string'), array('name' => 'orderingDirection', 'transform' => 'string'), array('name' => 'language', 'transform' => 'string'));
             // Add read list response messages
             $outputFields = array(array('name' => 'list', 'transform' => 'arrayrequired', 'fields' => array(array('name' => 'item', 'maxOccurs' => 'unbounded', 'transform' => 'arrayrequired', 'fields' => RApiSoapHelper::getOutputResources($this->webserviceXml->operations->read->list, 'listItem')))));
             $this->addOperation($this->wsdl, 'readList', $inputFields, $outputFields, true, true);
         }
         // Read item
         if (isset($this->webserviceXml->operations->read->item)) {
             // Add read item messages
             $inputFields = array_merge(RApiHalHelper::getFieldsArray($this->webserviceXml->operations->read->item, true), array(array('name' => 'language', 'transform' => 'string')));
             // Add read item response messages
             $outputFields = array(array('name' => 'item', 'typeName' => 'item', 'transform' => 'arrayrequired', 'fields' => RApiSoapHelper::getOutputResources($this->webserviceXml->operations->read->item)));
             $this->addOperation($this->wsdl, 'readItem', $inputFields, $outputFields, false, true);
         }
         // Create operation
         if (isset($this->webserviceXml->operations->create)) {
             // Add create messages
             $inputFields = RApiHalHelper::getFieldsArray($this->webserviceXml->operations->create);
             // Add create response messages
             $outputFields = array(RApiSoapHelper::getResultResource($this->webserviceXml->operations->create));
             $this->addOperation($this->wsdl, 'create', $inputFields, $outputFields, true);
         }
         // Update operation
         if (isset($this->webserviceXml->operations->update)) {
             // Add update messages
             $inputFields = RApiHalHelper::getFieldsArray($this->webserviceXml->operations->update);
             // Add update response messages
             $outputFields = array(RApiSoapHelper::getResultResource($this->webserviceXml->operations->update));
             $this->addOperation($this->wsdl, 'update', $inputFields, $outputFields, true);
         }
         // Delete operation
         if (isset($this->webserviceXml->operations->delete)) {
             // Add delete messages
             $inputFields = RApiHalHelper::getFieldsArray($this->webserviceXml->operations->delete, true);
             // Add delete response messages
             $outputFields = array(RApiSoapHelper::getResultResource($this->webserviceXml->operations->delete));
             $this->addOperation($this->wsdl, 'delete', $inputFields, $outputFields);
         }
         // Task operation
         if (isset($this->webserviceXml->operations->task)) {
             foreach ($this->webserviceXml->operations->task->children() as $taskName => $task) {
                 // Add task messages
                 $inputFields = RApiHalHelper::getFieldsArray($task);
                 // Add task response messages
                 $outputFields = array(RApiSoapHelper::getResultResource($task));
                 $this->addOperation($this->wsdl, 'task_' . $taskName, $inputFields, $outputFields, true);
             }
         }
     }
     return $this->wsdl;
 }
Exemple #5
0
 /**
  * Method to save the form data to XML file.
  *
  * @param   array  $data  The form data.
  *
  * @return  boolean  True on success, False on error.
  *
  * @throws  RuntimeException
  *
  * @since   1.4
  */
 public function saveXml($data)
 {
     $dataRegistry = new JRegistry($data);
     $item = null;
     if (empty($data['main']['name'])) {
         $this->setError(JText::_('COM_REDCORE_WEBSERVICE_NAME_FIELD_CANNOT_BE_EMPTY'));
         return false;
     }
     if (!empty($data['main']['id'])) {
         $item = $this->getItem($data['main']['id']);
     }
     $client = $dataRegistry->get('main.client', 'site');
     $name = $dataRegistry->get('main.name', '');
     $version = $dataRegistry->get('main.version', '1.0.0');
     $folder = $dataRegistry->get('main.path', '');
     $folder = !empty($folder) ? JPath::clean('/' . $folder) : '';
     if (!JFolder::exists(RApiHalHelper::getWebservicesPath() . $folder)) {
         JFolder::create(RApiHalHelper::getWebservicesPath() . $folder);
     }
     $fullPath = JPath::clean(RApiHalHelper::getWebservicesPath() . $folder . '/' . $client . '.' . $name . '.' . $version . '.xml');
     $xml = new SimpleXMLElement('<?xml version="1.0"?><apiservice client="' . $client . '"></apiservice>');
     $xml->addChild('name', $dataRegistry->get('main.title', $name));
     $xml->addChild('author', $dataRegistry->get('main.author', ''));
     $xml->addChild('copyright', $dataRegistry->get('main.copyright', ''));
     $xml->addChild('description', $dataRegistry->get('main.description', ''));
     $configXml = $xml->addChild('config');
     $configXml->addChild('name', $dataRegistry->get('main.name', ''));
     $configXml->addChild('version', $version);
     $configXml->addChild('authorizationAssetName', $dataRegistry->get('main.authorizationAssetName', ''));
     $operationsXml = $xml->addChild('operations');
     $readXml = null;
     $taskXml = null;
     foreach ($data as $operationName => $operation) {
         if ($operationName != 'main') {
             if (empty($operation['isEnabled'])) {
                 continue;
             }
             $operationNameSplit = explode('-', $operationName);
             if ($operationNameSplit[0] == 'read' && count($operationNameSplit) > 1) {
                 if (is_null($readXml)) {
                     $readXml = $operationsXml->addChild('read');
                 }
                 $operationXml = $readXml->addChild($operationNameSplit[1]);
             } elseif ($operationNameSplit[0] == 'task' && count($operationNameSplit) > 1) {
                 if (is_null($taskXml)) {
                     $taskXml = $operationsXml->addChild('task');
                 }
                 $operationXml = $taskXml->addChild($operationNameSplit[1]);
             } else {
                 $operationXml = $operationsXml->addChild($operationNameSplit[0]);
             }
             $this->getOperationAttributesFromPost($operationXml, $data, $operationName);
             $this->getFieldsFromPost($operationXml, $data, $operationName);
             $this->getResourcesFromPost($operationXml, $data, $operationName);
         }
     }
     // Needed for formatting
     $dom = dom_import_simplexml($xml)->ownerDocument;
     $dom->preserveWhiteSpace = false;
     $dom->formatOutput = true;
     if ($dom->save($fullPath)) {
         if (!empty($item->id)) {
             $folder = !empty($item->path) ? '/' . $item->path : '';
             $oldPath = JPath::clean(RApiHalHelper::getWebservicesPath() . $folder . '/' . $item->xmlFile);
             if ($oldPath != $fullPath) {
                 if (JFile::exists($oldPath)) {
                     JFile::delete($oldPath);
                 }
             }
         }
         $wsdl = RApiSoapHelper::generateWsdl($xml);
         $fullWsdlPath = substr($fullPath, 0, -4) . '.wsdl';
         return RApiSoapHelper::saveWsdlContentToPath($wsdl, $fullWsdlPath);
     }
     return false;
 }
Exemple #6
0
 /**
  * Read item
  *
  * @param   object  $data  Primary keys and $language
  *
  * @return  array
  */
 public function readItem($data)
 {
     // We are setting the operation of the webservice to Read
     $this->setOperation('read');
     $dataGet = $this->webservice->options->get('dataGet', array());
     $primaryKeysFromFields = RApiHalHelper::getFieldsArray($this->webservice->configuration->operations->read->item, true);
     // If there are no primary keys defined we will use id field as default
     if (empty($primaryKeysFromFields)) {
         $primaryKeysFromFields['id'] = array('transform' => 'int');
     }
     foreach ($primaryKeysFromFields as $primaryKey => $primaryKeyField) {
         $keyData = '';
         if (isset($data->{$primaryKey}) && $data->{$primaryKey} != '') {
             $keyData = $data->{$primaryKey};
         }
         $dataGet->{$primaryKey} = $this->webservice->transformField($primaryKeyField['transform'], $keyData, false);
     }
     // Handle different language switch
     $this->setLanguage((string) (isset($data->language) ? $data->language : ''));
     $this->webservice->options->set('dataGet', $dataGet);
     $this->webservice->options->set('task', '');
     $this->webservice->options->set('filterOutResourcesGroups', array('_links', '_messages'));
     $this->webservice->execute();
     $arr = $this->webservice->hal->toArray();
     $outputResources = RApiSoapHelper::getOutputResources($this->webservice->configuration->operations->read->item, '', true);
     $response = RApiSoapHelper::selectListResources($outputResources, array($arr));
     $final = new stdClass();
     $final->item = empty($response) ? array() : $response[0];
     $match = true;
     if (RApiHalHelper::isAttributeTrue($this->webservice->configuration->operations->read->item, 'enforcePKs', true)) {
         foreach ($primaryKeysFromFields as $primaryKey => $primaryKeyField) {
             if ($dataGet->{$primaryKey} != $final->item->{$primaryKey}) {
                 $match = false;
             }
         }
     }
     if (!$match) {
         $final = array();
     }
     if (!count((array) $final->item)) {
         $final = array();
     }
     return $final;
 }
Exemple #7
0
 /**
  * Method to register custom library.
  *
  * @return  void
  */
 public function onAfterInitialise()
 {
     if (defined('REDCORE_LIBRARY_LOADED')) {
         $apiName = JFactory::getApplication()->input->getString('api');
         if ($this->isApiEnabled($apiName)) {
             $input = JFactory::getApplication()->input;
             if (!empty($apiName)) {
                 try {
                     // We will disable all error messaging from PHP from the output
                     error_reporting(0);
                     ini_set('display_errors', 0);
                     JError::setErrorHandling(E_ERROR, 'message');
                     JFactory::getApplication()->clearHeaders();
                     $webserviceClient = $input->get->getString('webserviceClient', '');
                     $optionName = $input->get->getString('option', '');
                     $optionName = strpos($optionName, 'com_') === 0 ? substr($optionName, 4) : $optionName;
                     $viewName = $input->getString('view', '');
                     $version = $input->getString('webserviceVersion', '');
                     $token = $input->getString(RBootstrap::getConfig('oauth2_token_param_name', 'access_token'), '');
                     $apiName = ucfirst($apiName);
                     $method = strtoupper($input->getMethod());
                     $task = RApiHalHelper::getTask();
                     $data = RApi::getPostedData();
                     $dataGet = $input->get->getArray();
                     if (empty($webserviceClient)) {
                         $webserviceClient = JFactory::getApplication()->isAdmin() ? 'administrator' : 'site';
                     }
                     $options = array('api' => $apiName, 'optionName' => $optionName, 'viewName' => $viewName, 'webserviceVersion' => $version, 'webserviceClient' => $webserviceClient, 'method' => $method, 'task' => $task, 'data' => $data, 'dataGet' => $dataGet, 'accessToken' => $token, 'format' => $input->getString('format', $this->params->get('webservices_default_format', 'json')), 'id' => $input->getString('id', ''), 'absoluteHrefs' => $input->get->getBool('absoluteHrefs', true));
                     // Create instance of Api and fill all required options
                     $api = RApi::getInstance($options);
                     // Run the api task
                     $api->execute();
                     // Display output
                     $api->render();
                 } catch (Exception $e) {
                     $code = $e->getCode() > 0 ? $e->getCode() : 500;
                     if (strtolower($apiName) == 'soap') {
                         // We must have status of 200 for SOAP communication even if it is fault
                         $message = RApiSoapHelper::createSoapFaultResponse($e->getMessage());
                         header("Content-Type: soap+xml");
                         header("Content-length: " . strlen($message));
                         header("Status: 200");
                         echo $message;
                     } else {
                         // Set the server response code.
                         header('Status: ' . $code, true, $code);
                         // Check for defined constants
                         if (!defined('JSON_UNESCAPED_SLASHES')) {
                             define('JSON_UNESCAPED_SLASHES', 64);
                         }
                         // An exception has been caught, echo the message and exit.
                         echo json_encode(array('message' => $e->getMessage(), 'code' => $e->getCode(), 'type' => get_class($e)), JSON_UNESCAPED_SLASHES);
                     }
                 }
                 JFactory::getApplication()->close();
             }
         }
     }
 }
Exemple #8
0
 /**
  * Method to parse through a webservices element of the installation manifest and take appropriate
  * action.
  *
  * @param   JInstallerAdapter  $parent  class calling this method
  *
  * @return  boolean     True on success
  *
  * @since   1.3
  */
 public function installWebservices($parent)
 {
     $installer = $this->getInstaller();
     $manifest = $this->getManifest($parent);
     $src = $parent->getParent()->getPath('source');
     if (!$manifest) {
         return false;
     }
     $installer->setPath('source', $src);
     $element = $manifest->webservices;
     if (!$element || !count($element->children())) {
         // Either the tag does not exist or has no children therefore we return zero files processed.
         return false;
     }
     // Here we set the folder we are going to copy the files from.
     $folder = (string) $element->attributes()->folder;
     // This prevents trying to install webservice from other extension directory if webservice folder is not set
     if (!$folder || !is_dir($src . '/' . $folder)) {
         return false;
     }
     // Here we set the folder we are going to copy the files to.
     $destination = JPath::clean(RApiHalHelper::getWebservicesPath());
     $source = $src . '/' . $folder;
     $copyFiles = $this->prepareFilesForCopy($element, $source, $destination);
     // Copy the webservice XML files
     $return = $installer->copyFiles($copyFiles, true);
     // Recreate or create new SOAP WSDL files
     if (method_exists('RApiSoapHelper', 'generateWsdlFromFolder')) {
         foreach ($element->children() as $file) {
             RApiSoapHelper::generateWsdlFromFolder($destination . '/' . $file);
         }
     }
     return $return;
 }