cloudwords-8.x-1.x-dev/lib/cloudwords_client.php

lib/cloudwords_client.php
<?php

/*
 * Copyright 2011, Cloudwords, Inc.
 *
 * Licensed under the API LICENSE AGREEMENT, Version 1.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.cloudwords.com/developers/license-1.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.
 */

require_once('cloudwords_api.php');

// check package dependencies
if( !function_exists('curl_init') ) {
  $params = ['error_message' => 'The Cloudwords API PHP SDK requires the CURL PHP extension.'];
  throw new CloudwordsApiException(CloudwordsApiException::DEPENDENCY_EXCEPTION, $params);
}
if( !function_exists('json_decode') ) {
  $params = ['error_message' => 'The Cloudwords API PHP SDK requires the JSON PHP extension.'];
  throw new CloudwordsApiException(CloudwordsApiException::DEPENDENCY_EXCEPTION, $params);
}

/**
 * Basic implementation of the Cloudwords API client.
 *
 * @author Douglas Kim <doug@cloudwords.com>
 * @since 1.0
 */
class CloudwordsClient implements CloudwordsAPI {

  /**
   * Constants
   */
  const AUTHORIZATION_HEADER = 'Authorization: ';
  const CONTENT_TYPE_HEADER = 'Content-Type: ';
  const CONTENT_TYPE_JSON = 'application/json';
  const CONTENT_TYPE_MULTIPART_FORM_DATA = 'multipart/form-data';
  const REQUEST_TYPE_GET = 'GET';
  const REQUEST_TYPE_POST = 'POST';
  const REQUEST_TYPE_PUT = 'PUT';

  /**
   * Member variables
   */

  // The domain + version for connecting to the API (e.g. https://api.cloudwords.com/v1)
  private $base_url_with_version;

  // The authorization token to validate identify when accessing the Cloudwords API
  private $auth_token;

  // The timeout in seconds until a connection is established. A timeout value of zero is
  // interpreted as an infinite timeout.
  private $connection_timeout = 30;

  // The socket timeout in seconds, which is the timeout for waiting for data or, put differently,
  // a maximum period inactivity between two consecutive data packets). A timeout value of zero is
  // interpreted as an infinite timeout.
  private $socket_timeout = 60;

  // The max concurrent connections the client can establish against the Cloudwords API
  private $max_total_connections = 3;

  /**
   * The CloudwordsProject class to instansiate.
   */
  protected $project_class = '\Drupal\cloudwords\CloudwordsProject';

  /**
   * Convenience constructor that provides default configuration.
   *
   * @param string $base_api_url The base domain of the Cloudwords API
   * @param integer $version The version of the Cloudwords API to use
   * @param string $auth_token The authorization token to validate identify when accessing the Cloudwords API
   */
  public function __construct($base_api_url, $version, $auth_token) {
    $this->base_url_with_version = $base_api_url . '/' . $version;
    $this->auth_token = $auth_token;
  }

  /**
   * Private methods
   */
  private function init() {
    $conn = curl_init();
    curl_setopt($conn, CURLOPT_RETURNTRANSFER, true);
    curl_setopt($conn, CURLOPT_CONNECTTIMEOUT, $this->connection_timeout);
    curl_setopt($conn, CURLOPT_TIMEOUT, $this->socket_timeout);
    curl_setopt($conn, CURLOPT_MAXCONNECTS, $this->max_total_connections);
    return $conn;
  }

  private function close($conn) {
    curl_close($conn);
  }

  private function get($url, $accept_content_type, $body_content_type) {
    $conn = $this->init();
    curl_setopt($conn, CURLOPT_URL, $url);
    curl_setopt($conn, CURLOPT_HTTPHEADER, $this->get_headers($body_content_type));
    $response = $data = $this->execute($conn, $url, self::REQUEST_TYPE_GET);
    $data = $this->get_request_data($response, $accept_content_type);
    $this->close($conn);
    return $data;
  }

  private function post($url, $params, $accept_content_type, $body_content_type) {
    $conn = $this->init();
    curl_setopt($conn, CURLOPT_URL, $url);
    curl_setopt($conn, CURLOPT_HTTPHEADER, $this->get_headers($body_content_type));
    curl_setopt($conn, CURLOPT_POST, count($params));
    curl_setopt($conn, CURLOPT_POSTFIELDS, $body_content_type == self::CONTENT_TYPE_JSON ? json_encode($params) : $params);
    $response = $this->execute($conn, $url, self::REQUEST_TYPE_POST);
    $data = $this->get_request_data($response, $accept_content_type);
    $this->close($conn);
    return $data;
  }

  private function put($url, $params, $accept_content_type, $body_content_type) {
    $conn = $this->init();
    curl_setopt($conn, CURLOPT_URL, $url);
    curl_setopt($conn, CURLOPT_HTTPHEADER, $this->get_headers($body_content_type));
    curl_setopt($conn, CURLOPT_CUSTOMREQUEST, self::REQUEST_TYPE_PUT);
    curl_setopt($conn, CURLOPT_POSTFIELDS, $body_content_type == self::CONTENT_TYPE_JSON ? json_encode($params) : $params);
    $response = $this->execute($conn, $url, self::REQUEST_TYPE_PUT);
    $data = $this->get_request_data($response, $accept_content_type);
    $this->close($conn);
    return $data;
  }

  private function get_headers($body_content_type) {
    $headers = [];
    $headers[] = self::AUTHORIZATION_HEADER . $this->auth_token;
    if( $body_content_type == self::CONTENT_TYPE_JSON ) {
      $headers[] = self::CONTENT_TYPE_HEADER . self::CONTENT_TYPE_JSON;
    } else if( $body_content_type == self::CONTENT_TYPE_MULTIPART_FORM_DATA ) {
      $headers[] = self::CONTENT_TYPE_HEADER . self::CONTENT_TYPE_MULTIPART_FORM_DATA;
    }
    return $headers;
  }

  private function get_request_data($data, $content_type) {
    if( $content_type == self::CONTENT_TYPE_JSON ) {
      return json_decode($data, true);
    } else if( $content_type == self::CONTENT_TYPE_MULTIPART_FORM_DATA ) {
      return $data;
    } else {
      $params = ['content_type' => $content_type];
      throw new CloudwordsApiException(CloudwordsApiException::UNSUPPORTED_CONTENT_TYPE_EXCEPTION, $params);
    }
  }

  private function execute($conn, $url, $request_type) {
    // Skip SSL certificate verification
    curl_setopt($conn, CURLOPT_SSL_VERIFYPEER, FALSE);
    $data = curl_exec($conn);
    if (curl_errno($conn)) {
      $params = ['error_message' => curl_error($conn)];
      throw new CloudwordsApiException(CloudwordsApiException::REQUEST_EXCEPTION, $params);
    }
    $http_status_code = curl_getinfo($conn, CURLINFO_HTTP_CODE);
    if ($http_status_code === 200 || $http_status_code === 201) {
      return $data;
    } else {
      $params = ['http_status_code' => $http_status_code,
        'request_type' => $request_type,
        'request_url' => $url,
      ];
      if ($http_status_code === 404) {
        $params['error_message'] = 'Not Found';
        $error_response = json_decode($data);
        if (isset($error_response->{'error'})) {
          $params['error_message'] = $error_response->{'error'};
        }
        return new CloudwordsApiException(CloudwordsApiException::REQUEST_EXCEPTION, $params);
      } else {
        $error_response = json_decode($data);
        $params['error_message'] = $error_response->{'error'};
        return new CloudwordsApiException(CloudwordsApiException::API_EXCEPTION, $params);
      }
    }
  }

  private function curlFileFormat(&$params){
    if(is_array($params) == true){
      // Check each post field
      foreach($params as $key => $value){
        // Convert values for keys starting with '@' prefix
        if(strpos($value, '@') === 0){
          // Get the file name
          $filename = ltrim($value, '@');
          // Convert the value to the new class
          $params[$key] = new CURLFile($filename);
        }
      }
    }
  }

  /**
   * Public methods
   */

  public function getBaseUrlWithVersion() {
    return $this->base_url_with_version;
  }

  public function getAuthToken() {
    return $this->auth_token;
  }

  public function getConnectionTimeout() {
    return $this->connection_timeout;
  }

  public function getSocketTimeout() {
    return $this->socket_timeout;
  }

  public function getMaxTotalConnections() {
    return $this->max_total_connections;
  }

  public function get_projects($params = []) {
    $open_projects = [];
    $project_metadata = $this->get($this->base_url_with_version . '/project.json', self::CONTENT_TYPE_JSON, self::CONTENT_TYPE_JSON);
    return $this->project_factory($project_metadata);
    foreach( $projects_metadata as $project_metadata ) {
      $open_projects[] = $this->project_factory($project_metadata);
    }
    return $open_projects;
  }

  // @todo deprecated - remove
  public function get_open_projects() {
    $open_projects = [];
    $projects_metadata = $this->get($this->base_url_with_version . '/project/open.json', self::CONTENT_TYPE_JSON, self::CONTENT_TYPE_JSON);
    foreach( $projects_metadata as $project_metadata ) {
      $open_projects[] = $this->project_factory($project_metadata);
    }
    return $open_projects;
  }

  // @todo deprecated - remove
  public function get_closed_projects() {
    $closed_projects = [];
    $projects_metadata = $this->get($this->base_url_with_version . '/project/closed.json', self::CONTENT_TYPE_JSON, self::CONTENT_TYPE_JSON);
    foreach( $projects_metadata as $project_metadata ) {
      $closed_projects[] = $this->project_factory($project_metadata);
    }
    return $closed_projects;
  }

  public function set_project_class($class) {
    $this->project_class = $class;
  }

  protected function project_factory($data) {
    require_once \Drupal::root() . '/'. drupal_get_path('module', 'cloudwords') . '/src/CloudwordsDrupalProject.php';
    $project_class = $this->project_class;
    return new $project_class($data);
  }

  public function get_project($project_id) {
    $project_metadata = $this->get($this->base_url_with_version . '/project/' . $project_id . '.json', self::CONTENT_TYPE_JSON, self::CONTENT_TYPE_JSON);
    return $this->project_factory($project_metadata);
  }

  public function create_project($params) {
    $project_metadata = $this->post($this->base_url_with_version . '/project', $params, self::CONTENT_TYPE_JSON, self::CONTENT_TYPE_JSON);
    return $this->project_factory($project_metadata);
  }

  public function update_project($params) {
    $project_metadata = $this->put($this->base_url_with_version . '/project/' . $params['id'], $params, self::CONTENT_TYPE_JSON, self::CONTENT_TYPE_JSON);
    return $this->project_factory($project_metadata);
  }

  public function upload_project_source($project_id, $zip_file) {
    $params = ['file' => '@' . $zip_file];
    $this->curlFileFormat($params);
    $source_metadata = $this->put($this->base_url_with_version . '/project/' . $project_id . '/file/source', $params, self::CONTENT_TYPE_JSON, self::CONTENT_TYPE_MULTIPART_FORM_DATA);
    return new \Drupal\cloudwords\CloudwordsFile($source_metadata);
  }

  public function get_project_source($project_id) {
    $source_metadata = $this->get($this->base_url_with_version . '/project/' . $project_id . '/file/source.json', self::CONTENT_TYPE_JSON, self::CONTENT_TYPE_JSON);
    return new \Drupal\cloudwords\CloudwordsFile($source_metadata);
  }

  public function download_source_file($project_id) {
    $source_metadata = $this->get_project_source($project_id);
    return $this->download_file_from_metadata($source_metadata);
  }

  public function upload_project_reference($project_id, $zip_file) {
    $params = ['file' => '@' . $zip_file];
    $this->curlFileFormat($params);
    $reference_metadata = $this->post($this->base_url_with_version . '/project/' . $project_id . '/file/reference', $params, self::CONTENT_TYPE_JSON, self::CONTENT_TYPE_MULTIPART_FORM_DATA);
    return new \Drupal\cloudwords\CloudwordsFile($reference_metadata);
  }

  public function update_project_reference($project_id, $document_id, $zip_file) {
    $params = ['file' => '@' . $zip_file];
    $this->curlFileFormat($params);
    $reference_metadata = $this->put($this->base_url_with_version . '/project/' . $project_id . '/file/reference/' . $document_id, $params, self::CONTENT_TYPE_JSON, self::CONTENT_TYPE_MULTIPART_FORM_DATA);
    return new \Drupal\cloudwords\CloudwordsFile($reference_metadata);
  }

  public function get_reviewer_instruction($project_id, $language_code) {
    return $this->get($this->base_url_with_version . '/project/' . $project_id . '/language/' . $language_code . '/reviewer-instructions.json', self::CONTENT_TYPE_JSON, self::CONTENT_TYPE_JSON);
  }

  public function create_reviewer_instruction($project_id, $language_code, $content) {
    return $this->post($this->base_url_with_version . '/project/' . $project_id . '/language/' . $language_code . '/reviewer-instructions', $content, self::CONTENT_TYPE_JSON, self::CONTENT_TYPE_JSON);
  }

  /**
   * Gets the reference files for a given project.
   *
   * @param int $project_id
   *   A project id.
   *
   * @return CloudwordsFile[]
   *   A list of reference files.
   */
  public function get_project_references($project_id) {
    $project_references = [];
    $references_metadata = $this->get($this->base_url_with_version . '/project/' . $project_id . '/file/reference.json', self::CONTENT_TYPE_JSON, self::CONTENT_TYPE_JSON);
    if(is_array($references_metadata)) {
      foreach ($references_metadata as $reference_metadata) {
        $project_references[] = new \Drupal\cloudwords\CloudwordsFile($reference_metadata);
      }
    }
    return $project_references;
  }

  public function get_project_reference($project_id, $document_id) {
    $file_metadata = $this->get($this->base_url_with_version . '/project/' . $project_id . '/file/reference/' . $document_id . '.json', self::CONTENT_TYPE_JSON, self::CONTENT_TYPE_JSON);
    return new \Drupal\cloudwords\CloudwordsFile($file_metadata);
  }

  public function download_reference_file($project_id, $document_id) {
    $file_metadata = $this->get_project_reference($project_id, $document_id);
    return $this->download_file_from_metadata($file_metadata);
  }

  public function get_master_project_translated_file($project_id) {
    $file_metadata = $this->get($this->base_url_with_version . '/project/' . $project_id . '/file/translated.json', self::CONTENT_TYPE_JSON, self::CONTENT_TYPE_JSON);
    return new \Drupal\cloudwords\CloudwordsFile($file_metadata);
  }

  public function download_master_translated_file($project_id) {
    $file_metadata = $this->get_master_project_translated_file($project_id);
    return $this->download_file_from_metadata($file_metadata);
  }

  public function get_project_translated_files($project_id) {
    $project_translated_files = [];
    $files_metadata = $this->get($this->base_url_with_version . '/project/' . $project_id . '/file/translated/language.json', self::CONTENT_TYPE_JSON, self::CONTENT_TYPE_JSON);
    foreach( $files_metadata as $file_metadata ) {
      $project_translated_files[] = new \Drupal\cloudwords\CloudwordsFile($file_metadata);
    }
    return $project_translated_files;
  }

  public function get_project_translated_file($project_id, $language) {
    $file_metadata = $this->get($this->base_url_with_version . '/project/' . $project_id . '/file/translated/language/' . $language . '.json', self::CONTENT_TYPE_JSON, self::CONTENT_TYPE_JSON);
    return new \Drupal\cloudwords\CloudwordsFile($file_metadata);
  }

  public function approve_project_language($project_id, $language) {
  $params = [
    'status' => [
      'code' => 'approved',
    ],
  ];
    $file_metadata = $this->put($this->base_url_with_version . '/project/' . $project_id . '/file/translated/language/' . $language . '.json', $params, self::CONTENT_TYPE_JSON, self::CONTENT_TYPE_JSON);
    return new CloudwordsFile($file_metadata);
  }

  public function download_translated_file($project_id, $language) {
    $file_metadata = $this->get_project_translated_file($project_id, $language);
    return $this->download_file_from_metadata($file_metadata);
  }

  public function download_file_from_metadata($metadata) {
    if( !is_null($metadata) && !is_null($metadata->getContentPath()) ) {
      return $this->get($metadata->getContentPath(), self::CONTENT_TYPE_MULTIPART_FORM_DATA, self::CONTENT_TYPE_JSON);
    }
    return NULL;
  }

  public function request_bids_for_project($project_id, $preferred_vendors, $do_let_cloudwords_choose) {
    $params = ['preferredVendors' => $preferred_vendors,
                    'doLetCloudwordsChoose' => $do_let_cloudwords_choose];
    $bid_request = $this->post($this->base_url_with_version . '/project/' . $project_id . '/bid-request', $params, self::CONTENT_TYPE_JSON, self::CONTENT_TYPE_JSON);
    return new CloudwordsBidRequest($bid_request);
  }

  public function get_current_bid_request_for_project($project_id) {
    $bid_request = $this->get($this->base_url_with_version . '/project/' . $project_id . '/bid-request/current.json', self::CONTENT_TYPE_JSON, self::CONTENT_TYPE_JSON);
    return new CloudwordsBidRequest($bid_request);
  }

  public function get_preferred_vendors() {
    $preferred_vendors = [];
    $vendors = $this->get($this->base_url_with_version . '/vendor/preferred.json', self::CONTENT_TYPE_JSON, self::CONTENT_TYPE_JSON);
    foreach( $vendors as $vendor ) {
      $preferred_vendors[] = new CloudwordsVendor($vendor);
    }
    return $preferred_vendors;
  }

  public function get_source_languages() {
    $source_languages = [];
    $languages = $this->get($this->base_url_with_version . '/org/settings/project/language/source.json', self::CONTENT_TYPE_JSON, self::CONTENT_TYPE_JSON);
    foreach( $languages as $language ) {
      $source_languages[] = new CloudwordsLanguage($language);
    }
    return $source_languages;
  }

  public function get_target_languages() {
    $target_languages = [];
    $languages = $this->get($this->base_url_with_version . '/org/settings/project/language/target.json', self::CONTENT_TYPE_JSON, self::CONTENT_TYPE_JSON);
    foreach( $languages as $language ) {
      $target_languages[] = new CloudwordsLanguage($language);
    }
    return $target_languages;
  }

  public function get_intended_uses() {
    $intended_uses = [];
    $uses = $this->get($this->base_url_with_version . '/org/settings/project/intended-use.json', self::CONTENT_TYPE_JSON, self::CONTENT_TYPE_JSON);
    foreach( $uses as $intended_use ) {
      $intended_uses[] = new CloudwordsIntendedUse($intended_use);
    }
    return $intended_uses;
  }

  public function get_vendor($vendor_id) {
    $vendor = $this->get($this->base_url_with_version . '/vendor/' . $vendor_id . '.json', self::CONTENT_TYPE_JSON, self::CONTENT_TYPE_JSON);
    return new CloudwordsVendor($vendor);
  }

  public function get_departments() {
    $departments = $this->get($this->base_url_with_version . '/department.json', self::CONTENT_TYPE_JSON, self::CONTENT_TYPE_JSON);
    return $departments;
  }

  public function get_source_bundle($project_id) {
    return $this->get($this->base_url_with_version . '/project/' . $project_id . '/file/source/document.json', self::CONTENT_TYPE_JSON, self::CONTENT_TYPE_JSON);
  }

  public function get_translated_bundles($project_id, $language_code) {
    return $this->get($this->base_url_with_version . '/project/' . $project_id . '/file/translated/language/'.$language_code.'/document.json', self::CONTENT_TYPE_JSON, self::CONTENT_TYPE_JSON);
  }

  public function upload_source_preview_bundle($project_id, $document_id, $zip_file) {
    $params = ['file' => '@' . $zip_file];
    $this->curlFileFormat($params);
    return $this->put($this->base_url_with_version . '/project/' . $project_id . '/file/source/document/'.$document_id.'/preview', $params, self::CONTENT_TYPE_JSON, self::CONTENT_TYPE_MULTIPART_FORM_DATA);
  }

  public function upload_translation_preview_bundle($project_id, $language_code, $document_id, $zip_file) {
    $params = ['file' => '@' . $zip_file];
    $this->curlFileFormat($params);
    return $this->put($this->base_url_with_version . '/project/' . $project_id . '/file/translated/language/'.$language_code.'/document/'.$document_id.'/preview', $params, self::CONTENT_TYPE_JSON, self::CONTENT_TYPE_MULTIPART_FORM_DATA);
  }

  public function get_translated_document_by_id($project_id, $language_code, $document_id, $type = 'xliff') {
    return $this->get($this->base_url_with_version . '/project/' . $project_id . '/file/translated/language/'.$language_code.'/document/'.$document_id.'/'.$type, self::CONTENT_TYPE_MULTIPART_FORM_DATA, self::CONTENT_TYPE_JSON);
  }

}

Главная | Обратная связь

drupal hosting | друпал хостинг | it patrol .inc