/** * Start Webservice request * Check webservice activation * Check autentication * Check resource * Check HTTP Method * Execute the action * Display the result * * @param string $key * @param string $method * @param string $url * @param string $params * @param string $inputXml * * @return array Returns an array of results (headers, content, type of resource...) */ public function fetch($key, $method, $url, $params, $bad_class_name, $inputXml = null) { // Time logger $this->_startTime = microtime(true); $this->objects = array(); // Error handler set_error_handler(array($this, 'webserviceErrorHandler')); ini_set('html_errors', 'off'); // Two global vars, for compatibility with the PS core... global $webservice_call, $display_errors; $webservice_call = true; $display_errors = strtolower(ini_get('display_errors')) != 'off'; // __PS_BASE_URI__ is from Shop::$current_base_uri $this->wsUrl = Tools::getHttpHost(true) . __PS_BASE_URI__ . 'api/'; // set the output object which manage the content and header structure and informations $this->objOutput = new WebserviceOutputBuilder($this->wsUrl); $this->_key = trim($key); $this->outputFormat = isset($params['output_format']) ? $params['output_format'] : $this->outputFormat; // Set the render object to build the output on the asked format (XML, JSON, CSV, ...) $this->objOutput->setObjectRender($this->getOutputObject($this->outputFormat)); $this->params = $params; // Check webservice activation and request authentication if ($this->webserviceChecks()) { if ($bad_class_name) { $this->setError(500, 'Class "' . htmlspecialchars($bad_class_name) . '" not found. Please update the class_name field in the webservice_account table.', 126); } // parse request url $this->method = $method; $this->urlSegment = explode('/', $url); $this->urlFragments = $params; $this->_inputXml = $inputXml; $this->depth = isset($this->urlFragments['depth']) ? (int) $this->urlFragments['depth'] : $this->depth; try { // Method below set a particular fonction to use on the price field for products entity // @see WebserviceRequest::getPriceForProduct() method // @see WebserviceOutputBuilder::setSpecificField() method //$this->objOutput->setSpecificField($this, 'getPriceForProduct', 'price', 'products'); if (isset($this->urlFragments['price'])) { $this->objOutput->setVirtualField($this, 'specificPriceForCombination', 'combinations', $this->urlFragments['price']); $this->objOutput->setVirtualField($this, 'specificPriceForProduct', 'products', $this->urlFragments['price']); } } catch (Exception $e) { $this->setError(500, $e->getMessage(), $e->getCode()); } if (isset($this->urlFragments['language'])) { $this->_available_languages = $this->filterLanguage(); } else { $this->_available_languages = Language::getIDs(); } if (empty($this->_available_languages)) { $this->setError(400, 'language is not available', 81); } // Need to set available languages for the render object. // Thus we can filter i18n field for the output // @see WebserviceOutputXML::renderField() method for example $this->objOutput->objectRender->setLanguages($this->_available_languages); // check method and resource if (empty($this->errors) && $this->checkResource() && $this->checkHTTPMethod()) { // The resource list is necessary for build the output $this->objOutput->setWsResources($this->resourceList); // if the resource is a core entity... if (!isset($this->resourceList[$this->urlSegment[0]]['specific_management']) || !$this->resourceList[$this->urlSegment[0]]['specific_management']) { // load resource configuration if ($this->urlSegment[0] != '') { /** @var ObjectModel $object */ $object = new $this->resourceList[$this->urlSegment[0]]['class'](); if (isset($this->resourceList[$this->urlSegment[0]]['parameters_attribute'])) { $this->resourceConfiguration = $object->getWebserviceParameters($this->resourceList[$this->urlSegment[0]]['parameters_attribute']); } else { $this->resourceConfiguration = $object->getWebserviceParameters(); } } $success = false; // execute the action switch ($this->method) { case 'GET': case 'HEAD': if ($this->executeEntityGetAndHead()) { $success = true; } break; case 'POST': if ($this->executeEntityPost()) { $success = true; } break; case 'PUT': if ($this->executeEntityPut()) { $success = true; } break; case 'DELETE': $this->executeEntityDelete(); break; } // Need to set an object for the WebserviceOutputBuilder object in any case // because schema need to get webserviceParameters of this object if (isset($object)) { $this->objects['empty'] = $object; } } else { $specificObjectName = 'WebserviceSpecificManagement' . ucfirst(Tools::toCamelCase($this->urlSegment[0])); if (!class_exists($specificObjectName)) { $this->setError(501, sprintf('The specific management class is not implemented for the "%s" entity.', $this->urlSegment[0]), 124); } else { $this->objectSpecificManagement = new $specificObjectName(); $this->objectSpecificManagement->setObjectOutput($this->objOutput)->setWsObject($this); try { $this->objectSpecificManagement->manage(); } catch (WebserviceException $e) { if ($e->getType() == WebserviceException::DID_YOU_MEAN) { $this->setErrorDidYouMean($e->getStatus(), $e->getMessage(), $e->getWrongValue(), $e->getAvailableValues(), $e->getCode()); } elseif ($e->getType() == WebserviceException::SIMPLE) { $this->setError($e->getStatus(), $e->getMessage(), $e->getCode()); } } } } } } $return = $this->returnOutput(); unset($webservice_call); unset($display_errors); return $return; }