dynamic_image_generator-1.0.x-dev/src/Controller/DynamicImageGeneratorAdminController.php

src/Controller/DynamicImageGeneratorAdminController.php
<?php

namespace Drupal\dynamic_image_generator\Controller;

use Drupal\Core\Controller\ControllerBase;
use Drupal\Core\Link;
use Drupal\Core\Url;
use Symfony\Component\DependencyInjection\ContainerInterface;
use Drupal\Core\Config\ConfigFactoryInterface;
use Drupal\Core\Entity\EntityTypeManagerInterface;

/**
 * Admin controller for Poster Generator overview and management.
 */
class DynamicImageGeneratorAdminController extends ControllerBase {

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

  /**
   * The entity type manager.
   *
   * @var \Drupal\Core\Entity\EntityTypeManagerInterface
   */
  protected $entityTypeManager;

  /**
   * Constructs a DynamicImageGeneratorAdminController object.
   *
   * @param \Drupal\Core\Config\ConfigFactoryInterface $config_factory
   *   The config factory.
   * @param \Drupal\Core\Entity\EntityTypeManagerInterface $entity_type_manager
   *   The entity type manager.
   */
  public function __construct(ConfigFactoryInterface $config_factory, EntityTypeManagerInterface $entity_type_manager) {
    $this->configFactory = $config_factory;
    $this->entityTypeManager = $entity_type_manager;
  }

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

  /**
   * Dynamic Image Generator admin overview page.
   *
   * @return array
   *   A render array for the overview page.
   */
  public function overview() {
    $build = [];

    // Page header
    $build['header'] = [
      '#type' => 'markup',
      '#markup' => '
        <div class="image-admin-header">
          <h1>Dynamic Image Generator</h1>
          <p>Create beautiful images from your content automatically using customizable HTML/CSS templates.</p>
        </div>
      ',
    ];

    // System status
    $build['status'] = $this->buildStatusSection();

    // Quick actions
    $build['actions'] = $this->buildActionsSection();

    // Getting started
    $build['getting_started'] = $this->buildGettingStartedSection();

    // Recent activity
    $build['recent'] = $this->buildRecentActivitySection();

    // Add CSS styling
    $build['#attached']['html_head'][] = [
      [
        '#type' => 'html_tag',
        '#tag' => 'style',
        '#value' => '
          .poster-admin-header {
            background: linear-gradient(135deg, #667eea 0%, #764ba2 100%);
            color: white;
            padding: 30px;
            border-radius: 12px;
            margin-bottom: 30px;
            text-align: center;
          }
          .poster-admin-header h1 {
            margin: 0 0 10px 0;
            font-size: 2.5em;
            font-weight: 300;
          }
          .poster-admin-header p {
            margin: 0;
            font-size: 1.2em;
            opacity: 0.9;
          }
          .status-grid {
            display: grid;
            grid-template-columns: repeat(auto-fit, minmax(250px, 1fr));
            gap: 20px;
            margin-bottom: 30px;
          }
          .status-card {
            background: white;
            border: 1px solid #e1e5e9;
            border-radius: 8px;
            padding: 20px;
            box-shadow: 0 2px 4px rgba(0,0,0,0.1);
          }
          .status-card h3 {
            margin: 0 0 10px 0;
            color: #2c3e50;
            font-size: 1.1em;
          }
          .status-indicator {
            display: inline-block;
            width: 12px;
            height: 12px;
            border-radius: 50%;
            margin-right: 8px;
          }
          .status-ok { background-color: #28a745; }
          .status-warning { background-color: #ffc107; }
          .status-error { background-color: #dc3545; }
          .action-buttons {
            display: grid;
            grid-template-columns: repeat(auto-fit, minmax(200px, 1fr));
            gap: 15px;
            margin-bottom: 30px;
          }
          .action-button {
            display: block;
            padding: 15px 20px;
            background: #007bff;
            color: white;
            text-decoration: none;
            border-radius: 8px;
            text-align: center;
            font-weight: 500;
            transition: background-color 0.2s;
          }
          .action-button:hover {
            background: #0056b3;
            color: white;
            text-decoration: none;
          }
          .action-button.secondary {
            background: #6c757d;
          }
          .action-button.secondary:hover {
            background: #545b62;
          }
          .getting-started {
            background: #f8f9fa;
            border: 1px solid #e9ecef;
            border-radius: 8px;
            padding: 20px;
          }
          .step-list {
            counter-reset: step-counter;
            list-style: none;
            padding: 0;
          }
          .step-list li {
            counter-increment: step-counter;
            margin-bottom: 15px;
            padding-left: 40px;
            position: relative;
          }
          .step-list li::before {
            content: counter(step-counter);
            position: absolute;
            left: 0;
            top: 0;
            background: #007bff;
            color: white;
            width: 24px;
            height: 24px;
            border-radius: 50%;
            display: flex;
            align-items: center;
            justify-content: center;
            font-size: 14px;
            font-weight: bold;
          }
        ',
      ],
      'poster_admin_overview_css',
    ];

    return $build;
  }

  /**
   * Build the system status section.
   *
   * @return array
   *   Status section render array.
   */
  protected function buildStatusSection() {
    $config = $this->configFactory->get('dynamic_image_generator.settings');
    
    // Check API configuration
    $api_configured = !empty($config->get('api_user_id')) && !empty($config->get('api_key'));
    
    // Count templates
    try {
      $template_count = $this->entityTypeManager
        ->getStorage('poster_entity')
        ->getQuery()
        ->accessCheck(FALSE)
        ->count()
        ->execute();
    } catch (\Exception $e) {
      $template_count = 0;
    }

    // Count generated posters
    try {
      $poster_count = $this->entityTypeManager
        ->getStorage('media')
        ->getQuery()
        ->condition('bundle', 'dynamic_image')
        ->accessCheck(FALSE)
        ->count()
        ->execute();
    } catch (\Exception $e) {
      $poster_count = 0;
    }

    $status_items = [
      [
        'title' => 'API Configuration',
        'status' => $api_configured ? 'ok' : 'warning',
        'message' => $api_configured ? 'API credentials configured' : 'API credentials needed',
        'details' => $api_configured 
          ? 'Ready to generate posters' 
          : Link::createFromRoute('Configure API settings', 'dynamic_image_generator.settings')->toString(),
      ],
      [
        'title' => 'Image Templates',
        'status' => $template_count > 0 ? 'ok' : 'warning',
        'message' => $template_count . ' template' . ($template_count != 1 ? 's' : '') . ' created',
        'details' => $template_count > 0 
          ? Link::createFromRoute('Manage templates', 'entity.poster_entity.collection')->toString()
          : Link::createFromRoute('Create your first template', 'entity.poster_entity.add_form')->toString(),
      ],
      [
        'title' => 'Generated Images',
        'status' => 'ok',
        'message' => $poster_count . ' image' . ($poster_count != 1 ? 's' : '') . ' generated',
        'details' => $poster_count > 0 
          ? Link::createFromRoute('View in media library', 'generated_dynamic_images.page_1')->toString()
          : 'No images generated yet',
      ],
      [
        'title' => 'System Health',
        'status' => 'ok',
        'message' => 'All systems operational',
        'details' => 'Module is ready for use',
      ],
    ];

    $build = [
      '#type' => 'details',
      '#title' => $this->t('System Status'),
      '#open' => TRUE,
    ];

    $build['status_grid'] = [
      '#type' => 'markup',
      '#markup' => '<div class="status-grid">',
    ];

    foreach ($status_items as $item) {
      $status_class = 'status-' . $item['status'];
      $build['status_grid']['#markup'] .= "
        <div class='status-card'>
          <h3>
            <span class='status-indicator {$status_class}'></span>
            {$item['title']}
          </h3>
          <div><strong>{$item['message']}</strong></div>
          <div><small>{$item['details']}</small></div>
        </div>
      ";
    }

    $build['status_grid']['#markup'] .= '</div>';

    return $build;
  }

  /**
   * Build the quick actions section.
   *
   * @return array
   *   Actions section render array.
   */
  protected function buildActionsSection() {
    $build = [
      '#type' => 'details',
      '#title' => $this->t('Quick Actions'),
      '#open' => TRUE,
    ];

    $build['actions'] = [
      '#type' => 'container',
      '#attributes' => ['class' => ['image-admin-actions']],
    ];

    $build['actions']['title'] = [
      '#type' => 'markup',
      '#markup' => '<h3>Quick Actions</h3>',
    ];

    $build['actions']['links'] = [
      '#theme' => 'item_list',
      '#items' => [
        Link::createFromRoute('Create New Template', 'entity.poster_entity.add_form', [], [
          'attributes' => ['class' => ['button', 'button--primary']],
        ]),
        Link::createFromRoute('Manage Templates', 'entity.poster_entity.collection', [], [
          'attributes' => ['class' => ['button']],
        ]),
        Link::createFromRoute('View Generated Images', 'generated_dynamic_images.page_1', [], [
          'attributes' => ['class' => ['button']],
        ]),
        Link::createFromRoute('API Settings', 'dynamic_image_generator.settings', [], [
          'attributes' => ['class' => ['button']],
        ]),
        Link::createFromRoute('Usage Examples', 'dynamic_image_generator.example', [], [
          'attributes' => ['class' => ['button']],
        ]),
      ],
      '#attributes' => ['class' => ['action-links']],
    ];

    return $build;
  }

  /**
   * Build the getting started section.
   *
   * @return array
   *   Getting started section render array.
   */
  protected function buildGettingStartedSection() {
    $config = $this->configFactory->get('dynamic_image_generator.settings');
    $api_configured = !empty($config->get('api_user_id')) && !empty($config->get('api_key'));

    $build = [
      '#type' => 'details',
      '#title' => $this->t('Getting Started'),
      '#open' => !$api_configured,
    ];

    $build['content'] = [
      '#type' => 'markup',
      '#markup' => '
        <div class="getting-started">
          <h3>Follow these steps to start generating posters:</h3>
          <ol class="step-list">
            <li>
              <strong>Configure API credentials</strong><br>
              <small>Get your API key from <a href="https://htmlcsstoimage.com" target="_blank">htmlcsstoimage.com</a> and configure it in the API settings.</small>
            </li>
            <li>
              <strong>Create a poster template</strong><br>
              <small>Design your poster using HTML and CSS. Use tokens to pull content from your entities.</small>
            </li>
            <li>
              <strong>Configure content types</strong><br>
              <small>Set which content types should automatically generate posters using your templates.</small>
            </li>
            <li>
              <strong>Test and generate</strong><br>
              <small>Create or edit content to automatically generate poster images.</small>
            </li>
          </ol>
          
          <h4>Need help?</h4>
          <ul>
            <li><a href="/admin/config/content/poster-generator/example">View template examples</a></li>
            <li><a href="https://htmlcsstoimage.com/docs" target="_blank">API documentation</a></li>
            <li><a href="/admin/reports/dblog?type%5B%5D=dynamic_image_generator" target="_blank">Check system logs</a></li>
          </ul>
        </div>
      ',
    ];

    return $build;
  }

  /**
   * Build the recent activity section.
   *
   * @return array
   *   Recent activity section render array.
   */
  protected function buildRecentActivitySection() {
    $build = [
      '#type' => 'details',
      '#title' => $this->t('Recent Activity'),
      '#open' => FALSE,
    ];

    try {
      // Get recent poster media
      $recent_posters = $this->entityTypeManager
        ->getStorage('media')
        ->loadByProperties([
          'bundle' => 'poster',
        ]);

      if (!empty($recent_posters)) {
        // Sort by creation date
        uasort($recent_posters, function($a, $b) {
          return $b->getCreatedTime() - $a->getCreatedTime();
        });

        // Take only the 5 most recent
        $recent_posters = array_slice($recent_posters, 0, 5, TRUE);

        $items = [];
        foreach ($recent_posters as $poster) {
          $created = \Drupal::service('date.formatter')->format($poster->getCreatedTime(), 'short');
          $items[] = $this->t('@name - @date', [
            '@name' => $poster->getName(),
            '@date' => $created,
          ]);
        }

        $build['list'] = [
          '#theme' => 'item_list',
          '#title' => $this->t('Recently generated posters:'),
          '#items' => $items,
        ];
      } else {
        $build['empty'] = [
          '#type' => 'markup',
          '#markup' => '<p>No posters have been generated yet. ' . 
                      Link::createFromRoute('Create your first template', 'entity.poster_entity.add_form')->toString() . 
                      ' to get started.</p>',
        ];
      }
    } catch (\Exception $e) {
      $build['error'] = [
        '#type' => 'markup',
        '#markup' => '<p>Unable to load recent activity.</p>',
      ];
    }

    return $build;
  }

  /**
   * Test Built-in Image Generator.
   *
   * @return array
   *   Render array containing the result of the test.
   */
  public function testBuiltInGenerator() {
    $generator = \Drupal::service('image_creating_engine.generator');
    
    $test_html = '<div style="background: linear-gradient(45deg, #4CAF50, #45a049); color: white; padding: 30px; text-align: center; border-radius: 10px; font-family: Arial, sans-serif;"><h2 style="margin: 0 0 10px 0;">Built-in Generator Test</h2><p style="margin: 0;">Generated at ' . date('Y-m-d H:i:s') . '</p></div>';
    $test_css = 'body { margin: 0; padding: 20px; background: #f5f5f5; }';
    
    $result = $generator->generateImage($test_html, $test_css, [
      'width' => 500,
      'height' => 200,
      'format' => 'png'
    ]);
    
    if ($result && isset($result['url'])) {
      $build['success'] = [
        '#markup' => '<div class="messages messages--status">
          <strong>Built-in Generator is Working!</strong><br>
          <img src="' . $result['url'] . '" alt="Test image" style="max-width: 100%; border: 1px solid #ddd; margin-top: 10px;">
        </div>',
      ];
    } else {
      $build['error'] = [
        '#markup' => '<div class="messages messages--error">
          <strong>Built-in Generator Failed!</strong><br>
          Could not generate test image.
        </div>',
      ];
    }
    
    return $build;
  }
}

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

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