cc-1.0.x-dev/modules/cc_cex/src/Controller/PrivateApiController.php

modules/cc_cex/src/Controller/PrivateApiController.php
<?php

namespace Drupal\cc_cex\Controller;

use Drupal\Core\Controller\ControllerBase;
use Symfony\Component\DependencyInjection\ContainerInterface;
use Drupal\cc_cex\Service\CcxtService;
use Drupal\Core\Config\ConfigFactoryInterface;
use Drupal\Core\Url;
use Drupal\Core\Cache\Cache;
use Symfony\Component\HttpFoundation\RedirectResponse;

/**
 * Controller for private API operations.
 */
class PrivateApiController extends ControllerBase {

  /**
   * The CCXT service.
   *
   * @var \Drupal\cc_cex\Service\CcxtService
   */
  protected $ccxtService;

  /**
   * The config factory.
   *
   * @var \Drupal\Core\Config\ConfigFactoryInterface
   */
  protected $configFactory;

  /**
   * Constructs a new PrivateApiController object.
   *
   * @param \Drupal\cc_cex\Service\CcxtService $ccxt_service
   *   The CCXT service.
   * @param \Drupal\Core\Config\ConfigFactoryInterface $config_factory
   *   The config factory.
   */
  public function __construct(CcxtService $ccxt_service, ConfigFactoryInterface $config_factory) {
    $this->ccxtService = $ccxt_service;
    $this->configFactory = $config_factory;
  }

  /**
   * {@inheritdoc}
   */
  public static function create(ContainerInterface $container) {
    return new static(
      $container->get('cc_cex.ccxt_service'),
      $container->get('config.factory')
    );
  }

  /**
   * Display balances from enabled exchanges.
   */
  public function balances() {
    $build = [
      '#cache' => [
        'contexts' => ['user'],
        'tags' => ['config:cc.settings', 'cc:balances'],
        'max-age' => Cache::PERMANENT,
      ],
    ];

    $config = $this->configFactory->get('cc.settings');
    $enabled_exchanges = $config->get('enabled_exchanges') ?? '';
    $enabled_exchanges = !empty($enabled_exchanges) ? array_map('trim', explode(',', $enabled_exchanges)) : [];

    if (empty($enabled_exchanges)) {
      $build['empty'] = [
        '#markup' => '<p>' . $this->t('Please <a href="@settings">configure your exchange settings</a> first.', [
          '@settings' => '/admin/config/services/cc_cex-exchange',
        ]) . '</p>',
      ];
      return $build;
    }

    $build['actions'] = [
      '#type' => 'container',
      '#attributes' => ['class' => ['cc-actions']],
      'refresh' => [
        '#type' => 'link',
        '#title' => $this->t('Refresh Balances'),
        '#url' => Url::fromRoute('cc_cex.refresh_balances'),
        '#attributes' => [
          'class' => ['button', 'button--primary'],
        ],
      ],
    ];

    $rows = [];
    foreach ($enabled_exchanges as $exchange_id) {
      try {
        $balance = $this->ccxtService->getBalances($exchange_id);
        $exchange_balances = $this->filterNonZeroBalances($balance);
        
        foreach ($exchange_balances as $currency => $amounts) {
          $rows[] = [
            'exchange' => $exchange_id,
            'currency' => $currency,
            'free' => $amounts['free'],
            'used' => $amounts['used'],
            'total' => $amounts['total'],
          ];
        }
      }
      catch (\Exception $e) {
        \Drupal::logger('cc')->error('Error fetching balance for @exchange: @error', [
          '@exchange' => $exchange_id,
          '@error' => $exchange_id . ' ' . $e->getMessage(),
        ]);
      }
    }

    if (empty($rows)) {
      $build['empty'] = [
        '#markup' => '<p>' . $this->t('No balances found.') . '</p>',
      ];
      return $build;
    }

    $header = [
      'exchange' => $this->t('Exchange'),
      'currency' => $this->t('Currency'),
      'free' => $this->t('Available'),
      'used' => $this->t('In Orders'),
      'total' => $this->t('Total'),
    ];

    $build['table'] = [
      '#type' => 'table',
      '#header' => $header,
      '#attributes' => ['class' => ['cc-balances-table']],
      '#rows' => array_map(function($row) {
        return [
          'exchange' => ['data' => ['#markup' => $row['exchange']]],
          'currency' => ['data' => ['#markup' => $row['currency']]],
          'free' => ['data' => ['#markup' => number_format($row['free'], 8)]],
          'used' => ['data' => ['#markup' => number_format($row['used'], 8)]],
          'total' => ['data' => ['#markup' => number_format($row['total'], 8)]],
        ];
      }, $rows),
    ];

    return $build;
  }

  /**
   * Refresh balances and invalidate cache.
   */
  public function refreshBalances() {
    // Invalidate the balances cache tag
    Cache::invalidateTags(['cc:balances', 'config:cc.settings']);
    
    $this->messenger()->addStatus($this->t('Balances refreshed.'));
    
    return new RedirectResponse(Url::fromRoute('cc_cex.balances')->toString());
  }

  /**
   * Filter out zero balances and format the response.
   *
   * @param array $balance
   *   The balance.
   *
   * @return array
   *   The non-zero balances.
   */
  private function filterNonZeroBalances($balance) {
    $non_zero_balances = [];
    
    // Return empty array if balance is not valid
    if (!is_array($balance) || !isset($balance['total']) || !is_array($balance['total'])) {
      return $non_zero_balances;
    }
    
    foreach ($balance['total'] as $currency => $amount) {
      if ($amount > 0) {
        $non_zero_balances[$currency] = [
          'free' => $balance['free'][$currency] ?? 0,
          'used' => $balance['used'][$currency] ?? 0,
          'total' => $amount,
        ];
      }
    }
    return $non_zero_balances;
  }

}

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

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