Error 500 Internal Server Error

GET https://garage.farahtech.ma/stock

Exceptions

Impossible to access an attribute ("color") on a string variable ("out") in article/index.html.twig at line 301.

Exception

Twig\Error\ RuntimeError

Show exception properties
Twig\Error\RuntimeError {#1237
  -lineno: 301
  -rawMessage: "Impossible to access an attribute ("color") on a string variable ("out")."
  -source: Twig\Source {#872
    -code: """
      {% extends 'base.html.twig' %}\n
      \n
      {% block title %}Gestion du Stock - Garage Mohammed{% endblock %}\n
      \n
      {% block body %}\n
      <!-- Container principal pour la gestion des articles de stock -->\n
      <div class="max-w-7xl mx-auto space-y-8 animate-fade-in" data-controller="stock-management">\n
      \n
          <!-- En-tête avec breadcrumb et actions -->\n
          <div class="flex flex-col lg:flex-row lg:items-center lg:justify-between gap-4">\n
              <!-- Breadcrumb -->\n
              <nav class="flex items-center space-x-2 text-sm text-gray-600 mb-2">\n
                  <a href="{{ path('app_dashboard') }}" class="hover:text-blue-600 transition-colors">Accueil</a>\n
                  <svg class="w-4 h-4" fill="none" stroke="currentColor" viewBox="0 0 24 24">\n
                      <path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M9 5l7 7-7 7"/>\n
                  </svg>\n
                  <span class="text-gray-900 font-medium">Gestion du Stock</span>\n
              </nav>\n
      \n
              <!-- Titre et description -->\n
              <div class="flex-1">\n
                  <div class="flex items-center gap-4">\n
                      <div class="p-3 bg-gradient-to-r from-green-500 to-emerald-600 rounded-xl shadow-lg">\n
                          <svg class="w-8 h-8 text-white" fill="none" stroke="currentColor" viewBox="0 0 24 24">\n
                              <path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M20 7l-8-4-8 4m16 0l-8 4-8-4m16 0v10l-8 4-8-4V7"/>\n
                          </svg>\n
                      </div>\n
                      <div>\n
                          <h1 class="text-3xl font-bold text-gray-900 tracking-tight">Gestion du Stock</h1>\n
                          <p class="text-gray-600 mt-1">Gérez votre inventaire d'articles</p>\n
                      </div>\n
                  </div>\n
              </div>\n
      \n
              <!-- Actions principales -->\n
              <div class="flex items-center gap-3">\n
                  <button type="button"\n
                          class="inline-flex items-center gap-2 px-4 py-2 bg-gray-100 text-gray-700 rounded-lg hover:bg-gray-200 transition-all duration-200 shadow-sm">\n
                      <svg class="w-4 h-4" fill="none" stroke="currentColor" viewBox="0 0 24 24">\n
                          <path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M12 10v6m0 0l-3-3m3 3l3-3m2 8H7a2 2 0 01-2-2V5a2 2 0 012-2h5.586a1 1 0 01.707.293l5.414 5.414a1 1 0 01.293.707V19a2 2 0 01-2 2z"/>\n
                      </svg>\n
                      Exporter\n
                  </button>\n
                  <button type="button"\n
                          onclick="openStockModal()"\n
                          class="inline-flex items-center gap-2 px-6 py-3 bg-gradient-to-r from-green-600 to-emerald-600 text-white rounded-lg hover:from-green-700 hover:to-emerald-700 transition-all duration-200 shadow-lg hover:shadow-xl transform hover:-translate-y-0.5">\n
                      <svg class="w-5 h-5" fill="none" stroke="currentColor" viewBox="0 0 24 24">\n
                          <path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M12 4v16m8-8H4"/>\n
                      </svg>\n
                      Nouvel Article\n
                  </button>\n
              </div>\n
          </div>\n
      \n
          <!-- Statistiques du stock -->\n
          <div class="grid grid-cols-1 md:grid-cols-2 lg:grid-cols-4 gap-6">\n
              <!-- Total articles -->\n
              <div class="group relative bg-white rounded-2xl border border-gray-100 p-6 shadow-sm hover:shadow-xl transition-all duration-300 transform hover:-translate-y-1 overflow-hidden">\n
                  <div class="absolute inset-0 bg-gradient-to-br from-blue-50 to-blue-100 opacity-0 group-hover:opacity-100 transition-opacity duration-300"></div>\n
                  <div class="relative">\n
                      <div class="flex items-center justify-between">\n
                          <div>\n
                              <p class="text-xs font-semibold text-gray-500 uppercase tracking-wider mb-2">Total Articles</p>\n
                              <p class="text-3xl font-bold text-gray-900 mb-1">{{ stats.total_items }}</p>\n
                              <p class="text-sm text-blue-600 font-medium">En stock</p>\n
                          </div>\n
                          <div class="p-4 bg-blue-100 rounded-xl group-hover:bg-blue-200 transition-colors duration-300">\n
                              <svg class="w-7 h-7 text-blue-600" fill="none" stroke="currentColor" viewBox="0 0 24 24">\n
                                  <path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M20 7l-8-4-8 4m16 0l-8 4-8-4m16 0v10l-8 4-8-4V7"/>\n
                              </svg>\n
                          </div>\n
                      </div>\n
                  </div>\n
              </div>\n
      \n
              <!-- Stock bas -->\n
              <div class="group relative bg-white rounded-2xl border border-gray-100 p-6 shadow-sm hover:shadow-xl transition-all duration-300 transform hover:-translate-y-1 overflow-hidden">\n
                  <div class="absolute inset-0 bg-gradient-to-br from-red-50 to-red-100 opacity-0 group-hover:opacity-100 transition-opacity duration-300"></div>\n
                  <div class="relative">\n
                      <div class="flex items-center justify-between">\n
                          <div>\n
                              <p class="text-xs font-semibold text-gray-500 uppercase tracking-wider mb-2">Stock Bas</p>\n
                              <p class="text-3xl font-bold text-red-600 mb-1">{{ stats.low_stock_items }}</p>\n
                              <p class="text-sm text-red-600 font-medium">Réappro nécessaire</p>\n
                          </div>\n
                          <div class="p-4 bg-red-100 rounded-xl group-hover:bg-red-200 transition-colors duration-300">\n
                              <svg class="w-7 h-7 text-red-600" fill="none" stroke="currentColor" viewBox="0 0 24 24">\n
                                  <path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M12 9v2m0 4h.01m-6.938 4h13.856c1.54 0 2.502-1.667 1.732-2.5L13.732 4c-.77-.833-1.864-.833-2.464 0L3.34 16.5c-.77.833.192 2.5 1.732 2.5z"/>\n
                              </svg>\n
                          </div>\n
                      </div>\n
                  </div>\n
              </div>\n
      \n
              <!-- Valeur totale -->\n
              <div class="group relative bg-white rounded-2xl border border-gray-100 p-6 shadow-sm hover:shadow-xl transition-all duration-300 transform hover:-translate-y-1 overflow-hidden">\n
                  <div class="absolute inset-0 bg-gradient-to-br from-green-50 to-green-100 opacity-0 group-hover:opacity-100 transition-opacity duration-300"></div>\n
                  <div class="relative">\n
                      <div class="flex items-center justify-between">\n
                          <div>\n
                              <p class="text-xs font-semibold text-gray-500 uppercase tracking-wider mb-2">Valeur Totale</p>\n
                              <p class="text-3xl font-bold text-green-600 mb-1">{{ (stats.total_value / 1000)|number_format(0) }}K</p>\n
                              <p class="text-sm text-green-600 font-medium">MAD</p>\n
                          </div>\n
                          <div class="p-4 bg-green-100 rounded-xl group-hover:bg-green-200 transition-colors duration-300">\n
                              <svg class="w-7 h-7 text-green-600" fill="none" stroke="currentColor" viewBox="0 0 24 24">\n
                                  <path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M12 8c-1.657 0-3 .895-3 2s1.343 2 3 2 3 .895 3 2-1.343 2-3 2m0-8c1.11 0 2.08.402 2.599 1M12 8V7m0 1v8m0 0v1m0-1c-1.11 0-2.08-.402-2.599-1"/>\n
                              </svg>\n
                          </div>\n
                      </div>\n
                  </div>\n
              </div>\n
      \n
              <!-- Catégories -->\n
              <div class="group relative bg-white rounded-2xl border border-gray-100 p-6 shadow-sm hover:shadow-xl transition-all duration-300 transform hover:-translate-y-1 overflow-hidden">\n
                  <div class="absolute inset-0 bg-gradient-to-br from-purple-50 to-purple-100 opacity-0 group-hover:opacity-100 transition-opacity duration-300"></div>\n
                  <div class="relative">\n
                      <div class="flex items-center justify-between">\n
                          <div>\n
                              <p class="text-xs font-semibold text-gray-500 uppercase tracking-wider mb-2">Catégories</p>\n
                              <p class="text-3xl font-bold text-purple-600 mb-1">{{ stats.categories_count }}</p>\n
                              <p class="text-sm text-purple-600 font-medium">Types d'articles</p>\n
                          </div>\n
                          <div class="p-4 bg-purple-100 rounded-xl group-hover:bg-purple-200 transition-colors duration-300">\n
                              <svg class="w-7 h-7 text-purple-600" fill="none" stroke="currentColor" viewBox="0 0 24 24">\n
                                  <path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M7 7h.01M7 3h5c.512 0 1.024.195 1.414.586l7 7a2 2 0 010 2.828l-7 7a2 2 0 01-2.828 0l-7-7A1.994 1.994 0 013 12V7a4 4 0 014-4z"/>\n
                              </svg>\n
                          </div>\n
                      </div>\n
                  </div>\n
              </div>\n
          </div>\n
      \n
          <!-- Filtres avancés -->\n
          <div class="bg-white rounded-2xl border border-gray-100 p-6 shadow-sm">\n
              <div class="flex items-center gap-3 mb-4">\n
                  <div class="p-2 bg-gray-100 rounded-lg">\n
                      <svg class="w-5 h-5 text-gray-600" fill="none" stroke="currentColor" viewBox="0 0 24 24">\n
                          <path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M3 4a1 1 0 011-1h16a1 1 0 011 1v2.586a1 1 0 01-.293.707l-6.414 6.414a1 1 0 00-.293.707V17l-4 4v-6.586a1 1 0 00-.293-.707L3.293 7.414A1 1 0 013 6.707V4z"/>\n
                      </svg>\n
                  </div>\n
                  <h3 class="text-lg font-semibold text-gray-900">Filtres et Recherche</h3>\n
              </div>\n
      \n
              <form method="GET" class="grid grid-cols-1 md:grid-cols-2 lg:grid-cols-4 gap-4">\n
                  <!-- Recherche -->\n
                  <div class="space-y-2">\n
                      <label for="search" class="block text-sm font-medium text-gray-700">Recherche</label>\n
                      <div class="relative">\n
                          <input type="text"\n
                                 id="search"\n
                                 name="search"\n
                                 value="{{ filters.search }}"\n
                                 placeholder="Nom, référence, marque..."\n
                                 class="w-full pl-10 pr-4 py-3 border border-gray-200 rounded-lg focus:ring-2 focus:ring-green-500 focus:border-transparent transition-all duration-200">\n
                          <div class="absolute inset-y-0 left-0 pl-3 flex items-center pointer-events-none">\n
                              <svg class="w-5 h-5 text-gray-400" fill="none" stroke="currentColor" viewBox="0 0 24 24">\n
                                  <path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M21 21l-6-6m2-5a7 7 0 11-14 0 7 7 0 0114 0z"/>\n
                              </svg>\n
                          </div>\n
                      </div>\n
                  </div>\n
      \n
                  <!-- Catégorie -->\n
                  <div class="space-y-2">\n
                      <label for="category" class="block text-sm font-medium text-gray-700">Catégorie</label>\n
                      <select id="category"\n
                              name="category"\n
                              class="w-full px-4 py-3 border border-gray-200 rounded-lg focus:ring-2 focus:ring-green-500 focus:border-transparent transition-all duration-200 bg-white">\n
                          <option value="all">Toutes les catégories</option>\n
                          {% for key, label in categories %}\n
                              <option value="{{ key }}" {{ filters.category == key ? 'selected' : '' }}>{{ label }}</option>\n
                          {% endfor %}\n
                      </select>\n
                  </div>\n
      \n
                  <!-- Niveau de stock -->\n
                  <div class="space-y-2">\n
                      <label for="stock_level" class="block text-sm font-medium text-gray-700">Niveau de Stock</label>\n
                      <select id="stock_level"\n
                              name="stock_level"\n
                              class="w-full px-4 py-3 border border-gray-200 rounded-lg focus:ring-2 focus:ring-green-500 focus:border-transparent transition-all duration-200 bg-white">\n
                          <option value="all">Tous les niveaux</option>\n
                          <option value="low" {{ filters.stock_level == 'low' ? 'selected' : '' }}>🔴 Stock bas</option>\n
                          <option value="normal" {{ filters.stock_level == 'normal' ? 'selected' : '' }}>🟢 Stock normal</option>\n
                          <option value="high" {{ filters.stock_level == 'high' ? 'selected' : '' }}>🔵 Stock élevé</option>\n
                          <option value="out" {{ filters.stock_level == 'out' ? 'selected' : '' }}>❌ Rupture</option>\n
                      </select>\n
                  </div>\n
      \n
                  <div class="flex items-end gap-2">\n
                      <button type="submit"\n
                              class="flex-1 px-6 py-3 bg-green-600 text-white rounded-lg hover:bg-green-700 transition-all duration-200 shadow-md hover:shadow-lg transform hover:-translate-y-0.5 font-medium">\n
                          Filtrer\n
                      </button>\n
                      <a href="{{ path('app_stock_index') }}"\n
                         class="px-4 py-3 bg-gray-100 text-gray-700 rounded-lg hover:bg-gray-200 transition-all duration-200">\n
                          <svg class="w-5 h-5" fill="none" stroke="currentColor" viewBox="0 0 24 24">\n
                              <path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M4 4v5h.582m15.356 2A8.001 8.001 0 004.582 9m0 0H9m11 11v-5h-.581m0 0a8.003 8.003 0 01-15.357-2m15.357 2H15"/>\n
                          </svg>\n
                      </a>\n
                  </div>\n
              </form>\n
          </div>\n
      \n
          <!-- Tableau des articles -->\n
          <div class="bg-white rounded-2xl border border-gray-100 shadow-sm overflow-hidden">\n
              <div class="p-6 border-b border-gray-100 bg-gradient-to-r from-gray-50 to-white">\n
                  <div class="flex items-center justify-between">\n
                      <div>\n
                          <h3 class="text-xl font-bold text-gray-900">Inventaire du Stock</h3>\n
                          <p class="text-gray-600 mt-1">{{ articles|length }} articles trouvés</p>\n
                      </div>\n
                      <div class="flex items-center gap-2">\n
                          {% if stats.low_stock_items > 0 %}\n
                              <div class="flex items-center gap-2 px-3 py-2 bg-red-50 text-red-700 rounded-lg border border-red-200">\n
                                  <svg class="w-4 h-4" fill="none" stroke="currentColor" viewBox="0 0 24 24">\n
                                      <path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M12 9v2m0 4h.01m-6.938 4h13.856c1.54 0 2.502-1.667 1.732-2.5L13.732 4c-.77-.833-1.864-.833-2.464 0L3.34 16.5c-.77.833.192 2.5 1.732 2.5z"/>\n
                                  </svg>\n
                                  <span class="text-sm font-medium">{{ stats.low_stock_items }} articles en stock bas</span>\n
                              </div>\n
                          {% endif %}\n
                      </div>\n
                  </div>\n
              </div>\n
      \n
              {% if articles is empty %}\n
                  <!-- État vide -->\n
                  <div class="text-center py-16">\n
                      <div class="mx-auto w-32 h-32 bg-gradient-to-br from-green-100 to-emerald-100 rounded-full flex items-center justify-center mb-6">\n
                          <svg class="w-16 h-16 text-green-400" fill="none" stroke="currentColor" viewBox="0 0 24 24">\n
                              <path stroke-linecap="round" stroke-linejoin="round" stroke-width="1.5" d="M20 7l-8-4-8 4m16 0l-8 4-8-4m16 0v10l-8 4-8-4V7"/>\n
                          </svg>\n
                      </div>\n
                      <h3 class="text-xl font-semibold text-gray-900 mb-2">Aucun article trouvé</h3>\n
                      <p class="text-gray-600 mb-6 max-w-md mx-auto">Commencez par ajouter des articles à votre stock ou ajustez vos filtres de recherche</p>\n
                      <div class="flex items-center justify-center gap-3">\n
                          <button type="button"\n
                                  onclick="openStockModal()"\n
                                  class="inline-flex items-center gap-2 px-6 py-3 bg-gradient-to-r from-green-600 to-emerald-600 text-white rounded-lg hover:from-green-700 hover:to-emerald-700 transition-all duration-200 shadow-lg hover:shadow-xl transform hover:-translate-y-0.5">\n
                              <svg class="w-5 h-5" fill="none" stroke="currentColor" viewBox="0 0 24 24">\n
                                  <path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M12 4v16m8-8H4"/>\n
                              </svg>\n
                              Ajouter un article\n
                          </button>\n
                          <a href="{{ path('app_stock_index') }}"\n
                             class="inline-flex items-center gap-2 px-6 py-3 bg-gray-100 text-gray-700 rounded-lg hover:bg-gray-200 transition-all duration-200">\n
                              <svg class="w-5 h-5" fill="none" stroke="currentColor" viewBox="0 0 24 24">\n
                                  <path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M4 4v5h.582m15.356 2A8.001 8.001 0 004.582 9m0 0H9m11 11v-5h-.581m0 0a8.003 8.003 0 01-15.357-2m15.357 2H15"/>\n
                              </svg>\n
                              Réinitialiser les filtres\n
                          </a>\n
                      </div>\n
                  </div>\n
              {% else %}\n
                  <!-- Tableau des articles -->\n
                  <div class="overflow-x-auto">\n
                      <table class="w-full min-w-full table-modern">\n
                          <thead>\n
                              <tr class="border-b border-gray-200 bg-gray-50">\n
                                  <th class="text-left py-4 px-6 font-semibold text-gray-700 text-xs uppercase tracking-wide">Article</th>\n
                                  <th class="text-left py-4 px-6 font-semibold text-gray-700 text-xs uppercase tracking-wide">Catégorie</th>\n
                                  <th class="text-center py-4 px-6 font-semibold text-gray-700 text-xs uppercase tracking-wide">Stock</th>\n
                                  <th class="text-center py-4 px-6 font-semibold text-gray-700 text-xs uppercase tracking-wide">Prix Unit.</th>\n
                                  <th class="text-center py-4 px-6 font-semibold text-gray-700 text-xs uppercase tracking-wide">Valeur</th>\n
                                  <th class="text-center py-4 px-6 font-semibold text-gray-700 text-xs uppercase tracking-wide">Actions</th>\n
                              </tr>\n
                          </thead>\n
                          <tbody class="divide-y divide-gray-100">\n
                              {% for article in articles %}\n
                                  {% set stockStatus = article.stockStatus %}\n
                                  <tr class="hover:bg-gray-50 transition-colors duration-150">\n
                                      <td class="py-4 px-6">\n
                                          <div class="flex items-center gap-3">\n
                                              <div class="flex-shrink-0">\n
                                                  <div class="w-10 h-10 bg-gradient-to-br from-gray-100 to-gray-200 rounded-lg flex items-center justify-center">\n
                                                      <svg class="w-5 h-5 text-gray-600" fill="none" stroke="currentColor" viewBox="0 0 24 24">\n
                                                          <path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M20 7l-8-4-8 4m16 0l-8 4-8-4m16 0v10l-8 4-8-4V7"/>\n
                                                      </svg>\n
                                                  </div>\n
                                              </div>\n
                                              <div>\n
                                                  <div class="font-medium text-gray-900">{{ article.name }}</div>\n
                                                  {% if article.brand %}\n
                                                      <div class="text-sm text-gray-500">{{ article.brand }}</div>\n
                                                  {% endif %}\n
                                                  {% if article.partNumber %}\n
                                                      <div class="text-xs text-gray-400">Réf: {{ article.partNumber }}</div>\n
                                                  {% endif %}\n
                                              </div>\n
                                          </div>\n
                                      </td>\n
                                      <td class="py-4 px-6">\n
                                          <span class="inline-flex items-center px-2.5 py-1 rounded-full text-xs font-medium bg-gray-100 text-gray-800">\n
                                              {{ article.categoryLabel }}\n
                                          </span>\n
                                      </td>\n
                                      <td class="py-4 px-6 text-center">\n
                                          <div class="flex items-center justify-center gap-2">\n
                                              <span class="text-lg font-bold text-gray-900">{{ article.currentStock }}</span>\n
                                              <span class="inline-flex items-center px-2 py-1 rounded-full text-xs font-medium {{ stockStatus.color }}">\n
                                                  {{ stockStatus.label }}\n
                                              </span>\n
                                          </div>\n
                                          <div class="text-xs text-gray-500 mt-1">\n
                                              Min: {{ article.minStock }} | Max: {{ article.maxStock }}\n
                                          </div>\n
                                          {% if article.stockPercentage < 100 %}\n
                                              <div class="w-full bg-gray-200 rounded-full h-1.5 mt-2">\n
                                                  <div class="bg-{{ stockStatus.status == 'low' ? 'red' : (stockStatus.status == 'high' ? 'blue' : 'green') }}-500 h-1.5 rounded-full"\n
                                                       style="width: {{ article.stockPercentage }}%"></div>\n
                                              </div>\n
                                          {% endif %}\n
                                      </td>\n
                                      <td class="py-4 px-6 text-center">\n
                                          <span class="font-medium text-gray-900">{{ article.formattedPrice }}</span>\n
                                      </td>\n
                                      <td class="py-4 px-6 text-center">\n
                                          <span class="font-bold text-green-600">{{ article.formattedTotalValue }}</span>\n
                                      </td>\n
      \n
                                      <td class="py-4 px-6">\n
                                          <div class="flex items-center justify-center gap-1">\n
                                              <button onclick="viewStockItem({{ article.id }})"\n
                                                      class="inline-flex items-center justify-center w-8 h-8 text-blue-600 hover:text-blue-700 hover:bg-blue-50 rounded-lg transition-colors"\n
                                                      title="Voir">\n
                                                  <svg class="w-4 h-4" fill="none" stroke="currentColor" viewBox="0 0 24 24">\n
                                                      <path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M15 12a3 3 0 11-6 0 3 3 0 016 0z"/>\n
                                                      <path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M2.458 12C3.732 7.943 7.523 5 12 5c4.478 0 8.268 2.943 9.542 7-1.274 4.057-5.064 7-9.542 7-4.477 0-8.268-2.943-9.542-7z"/>\n
                                                  </svg>\n
                                              </button>\n
                                              <button onclick="editStockItem({{ article.id }})"\n
                                                      class="inline-flex items-center justify-center w-8 h-8 text-orange-600 hover:text-orange-700 hover:bg-orange-50 rounded-lg transition-colors"\n
                                                      title="Modifier">\n
                                                  <svg class="w-4 h-4" fill="none" stroke="currentColor" viewBox="0 0 24 24">\n
                                                      <path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M11 5H6a2 2 0 00-2 2v11a2 2 0 002 2h11a2 2 0 002-2v-5m-1.414-9.414a2 2 0 112.828 2.828L11.828 15H9v-2.828l8.586-8.586z"/>\n
                                                  </svg>\n
                                              </button>\n
                                              <button onclick="updateStock({{ article.id }}, '{{ article.name|e('js') }}')"\n
                                                      class="inline-flex items-center justify-center w-8 h-8 text-green-600 hover:text-green-700 hover:bg-green-50 rounded-lg transition-colors"\n
                                                      title="Mettre à jour le stock">\n
                                                  <svg class="w-4 h-4" fill="none" stroke="currentColor" viewBox="0 0 24 24">\n
                                                      <path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M7 16V4m0 0L3 8m4-4l4 4m6 0v12m0 0l4-4m-4 4l-4-4"/>\n
                                                  </svg>\n
                                              </button>\n
                                          </div>\n
                                      </td>\n
                                  </tr>\n
                              {% endfor %}\n
                          </tbody>\n
                      </table>\n
                  </div>\n
              {% endif %}\n
          </div>\n
      </div>\n
      \n
      <!-- Modal pour nouvel article/modification -->\n
      <div id="stock-modal" class="fixed inset-0 bg-black bg-opacity-20 hidden items-center justify-center z-50">\n
          <div class="bg-white rounded-lg shadow-xl max-w-4xl w-full mx-4 max-h-[90vh] overflow-y-auto">\n
              <div class="flex items-center justify-between p-6 border-b">\n
                  <h2 class="text-lg font-semibold" id="stock-modal-title">Nouvel Article</h2>\n
                  <button type="button" onclick="closeStockModal()" class="text-gray-400 hover:text-gray-600">\n
                      <svg class="w-6 h-6" fill="none" stroke="currentColor" viewBox="0 0 24 24">\n
                          <path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M6 18L18 6M6 6l12 12"/>\n
                      </svg>\n
                  </button>\n
              </div>\n
              <div id="stock-modal-content" class="p-6">\n
                  <!-- Le contenu sera chargé dynamiquement -->\n
              </div>\n
          </div>\n
      </div>\n
      \n
      <!-- Modal pour mise à jour du stock -->\n
      <div id="stock-update-modal" class="fixed inset-0 bg-black bg-opacity-20 hidden items-center justify-center z-50">\n
          <div class="bg-white rounded-lg shadow-xl max-w-md w-full mx-4">\n
              <div class="flex items-center justify-between p-6 border-b">\n
                  <h2 class="text-lg font-semibold">Mettre à jour le stock</h2>\n
                  <button type="button" onclick="closeStockUpdateModal()" class="text-gray-400 hover:text-gray-600">\n
                      <svg class="w-6 h-6" fill="none" stroke="currentColor" viewBox="0 0 24 24">\n
                          <path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M6 18L18 6M6 6l12 12"/>\n
                      </svg>\n
                  </button>\n
              </div>\n
              <div class="p-6">\n
                  <div class="mb-4">\n
                      <h3 class="font-medium text-gray-900" id="stock-update-item-name"></h3>\n
                  </div>\n
                  <form id="stock-update-form">\n
                      <div class="space-y-4">\n
                          <div>\n
                              <label class="block text-sm font-medium text-gray-700 mb-2">Type de mouvement</label>\n
                              <select id="movement-type" class="w-full px-3 py-2 border border-gray-200 rounded-lg focus:ring-2 focus:ring-green-500">\n
                                  <option value="in">Entrée de stock</option>\n
                                  <option value="out">Sortie de stock</option>\n
                              </select>\n
                          </div>\n
                          <div>\n
                              <label class="block text-sm font-medium text-gray-700 mb-2">Quantité</label>\n
                              <input type="number" id="movement-quantity" min="1" class="w-full px-3 py-2 border border-gray-200 rounded-lg focus:ring-2 focus:ring-green-500" placeholder="Ex: 10">\n
                          </div>\n
                          <div>\n
                              <label class="block text-sm font-medium text-gray-700 mb-2">Raison</label>\n
                              <input type="text" id="movement-reason" class="w-full px-3 py-2 border border-gray-200 rounded-lg focus:ring-2 focus:ring-green-500" placeholder="Ex: Réapprovisionnement, Utilisé pour réparation...">\n
                          </div>\n
                      </div>\n
                      <div class="flex justify-end gap-3 mt-6">\n
                          <button type="button" onclick="closeStockUpdateModal()" class="px-4 py-2 text-gray-700 bg-gray-100 rounded-lg hover:bg-gray-200">\n
                              Annuler\n
                          </button>\n
                          <button type="submit" class="px-4 py-2 bg-green-600 text-white rounded-lg hover:bg-green-700">\n
                              Mettre à jour\n
                          </button>\n
                      </div>\n
                  </form>\n
              </div>\n
          </div>\n
      </div>\n
      \n
      <script>\n
      // Variables globales pour la gestion du stock\n
      let currentStockItemId = null;\n
      \n
      // Fonctions pour les modals\n
      function openStockModal() {\n
          document.getElementById('stock-modal').classList.remove('hidden');\n
          document.getElementById('stock-modal').classList.add('flex');\n
          loadStockForm('{{ path('app_stock_new') }}', 'Nouvel Article');\n
      }\n
      \n
      function closeStockModal() {\n
          document.getElementById('stock-modal').classList.add('hidden');\n
          document.getElementById('stock-modal').classList.remove('flex');\n
      }\n
      \n
      function editStockItem(itemId) {\n
          openStockModal();\n
          loadStockForm(`/stock/${itemId}/edit`, 'Modifier l\'Article');\n
      }\n
      \n
      function viewStockItem(itemId) {\n
          window.location.href = `/stock/${itemId}`;\n
      }\n
      \n
      async function loadStockForm(url, title) {\n
          document.getElementById('stock-modal-title').textContent = title;\n
          document.getElementById('stock-modal-content').innerHTML = '<div class="text-center py-4">Chargement...</div>';\n
      \n
          try {\n
              const response = await fetch(url, {\n
                  headers: {\n
                      'X-Requested-With': 'XMLHttpRequest'\n
                  }\n
              });\n
              const html = await response.text();\n
              document.getElementById('stock-modal-content').innerHTML = html;\n
      \n
              // Attacher l'événement de soumission au nouveau formulaire\n
              const form = document.getElementById('stock-form');\n
              if (form) {\n
                  form.addEventListener('submit', handleStockFormSubmit);\n
              }\n
          } catch (error) {\n
              document.getElementById('stock-modal-content').innerHTML = '<div class="text-red-600 text-center py-4">Erreur lors du chargement</div>';\n
          }\n
      }\n
      \n
      // Gestion de la soumission du formulaire\n
      async function handleStockFormSubmit(e) {\n
          e.preventDefault();\n
      \n
          const form = e.target;\n
          const formData = new FormData(form);\n
          const submitButton = form.querySelector('button[type="submit"]');\n
      \n
          // Désactiver le bouton pendant la soumission\n
          submitButton.disabled = true;\n
          submitButton.innerHTML = '<span class="flex items-center gap-2"><svg class="animate-spin w-4 h-4" fill="none" viewBox="0 0 24 24"><circle class="opacity-25" cx="12" cy="12" r="10" stroke="currentColor" stroke-width="4"></circle><path class="opacity-75" fill="currentColor" d="m4 12a8 8 0 018-8V0C5.373 0 0 5.373 0 12h4zm2 5.291A7.962 7.962 0 014 12H0c0 3.042 1.135 5.824 3 7.938l3-2.647z"></path></svg>Enregistrement...</span>';\n
      \n
          try {\n
              const response = await fetch(form.action, {\n
                  method: 'POST',\n
                  body: formData,\n
                  headers: {\n
                      'X-Requested-With': 'XMLHttpRequest'\n
                  }\n
              });\n
      \n
              const contentType = response.headers.get('content-type');\n
      \n
              if (contentType && contentType.includes('application/json')) {\n
                  // Réponse JSON (succès ou erreur)\n
                  const result = await response.json();\n
      \n
                  if (result.success) {\n
                      closeStockModal();\n
                      // Recharger la page pour voir les changements\n
                      window.location.reload();\n
                  } else {\n
                      alert(result.message || 'Erreur lors de l\'enregistrement');\n
                  }\n
              } else {\n
                  // Réponse HTML (formulaire avec erreurs de validation)\n
                  const html = await response.text();\n
                  document.getElementById('stock-modal-content').innerHTML = html;\n
      \n
                  // Réattacher l'événement de soumission\n
                  const newForm = document.getElementById('stock-form');\n
                  if (newForm) {\n
                      newForm.addEventListener('submit', handleStockFormSubmit);\n
                  }\n
              }\n
          } catch (error) {\n
              alert('Erreur de connexion: ' + error.message);\n
          } finally {\n
              // Réactiver le bouton\n
              submitButton.disabled = false;\n
              submitButton.innerHTML = '<span class="flex items-center gap-2"><svg class="w-4 h-4" fill="none" stroke="currentColor" viewBox="0 0 24 24"><path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M12 4v16m8-8H4"/></svg>Ajouter l\'article</span>';\n
          }\n
      }\n
      \n
      // Gestion des mises à jour de stock\n
      function updateStock(itemId, itemName) {\n
          currentStockItemId = itemId;\n
          document.getElementById('stock-update-item-name').textContent = itemName;\n
          document.getElementById('stock-update-modal').classList.remove('hidden');\n
          document.getElementById('stock-update-modal').classList.add('flex');\n
      }\n
      \n
      function closeStockUpdateModal() {\n
          document.getElementById('stock-update-modal').classList.add('hidden');\n
          document.getElementById('stock-update-modal').classList.remove('flex');\n
          currentStockItemId = null;\n
      }\n
      \n
      // Soumission du formulaire de mise à jour du stock\n
      document.getElementById('stock-update-form').addEventListener('submit', async function(e) {\n
          e.preventDefault();\n
      \n
          if (!currentStockItemId) return;\n
      \n
          const type = document.getElementById('movement-type').value;\n
          const quantity = parseInt(document.getElementById('movement-quantity').value);\n
          const reason = document.getElementById('movement-reason').value;\n
      \n
          if (!quantity || quantity <= 0) {\n
              alert('Veuillez saisir une quantité valide');\n
              return;\n
          }\n
      \n
          if (!reason.trim()) {\n
              alert('Veuillez saisir une raison');\n
              return;\n
          }\n
      \n
          try {\n
              const response = await fetch(`/stock/${currentStockItemId}/update-stock`, {\n
                  method: 'POST',\n
                  headers: {\n
                      'Content-Type': 'application/json',\n
                      'X-Requested-With': 'XMLHttpRequest'\n
                  },\n
                  body: JSON.stringify({\n
                      type: type,\n
                      quantity: quantity,\n
                      reason: reason\n
                  })\n
              });\n
      \n
              const result = await response.json();\n
      \n
              if (result.success) {\n
                  closeStockUpdateModal();\n
                  location.reload(); // Recharger pour voir les changements\n
              } else {\n
                  alert(result.error || 'Erreur lors de la mise à jour');\n
              }\n
          } catch (error) {\n
              alert('Erreur de connexion: ' + error.message);\n
          }\n
      });\n
      </script>\n
      {% endblock %}\n
      """
    -name: "article/index.html.twig"
    -path: "/var/www/vhosts/farahtech.ma/garage/templates/article/index.html.twig"
  }
  -phpFile: "/var/www/vhosts/farahtech.ma/garage/vendor/twig/twig/src/Extension/CoreExtension.php"
  -phpLine: 1739
}
  1.                                     </span>
  2.                                 </td>
  3.                                 <td class="py-4 px-6 text-center">
  4.                                     <div class="flex items-center justify-center gap-2">
  5.                                         <span class="text-lg font-bold text-gray-900">{{ article.currentStock }}</span>
  6.                                         <span class="inline-flex items-center px-2 py-1 rounded-full text-xs font-medium {{ stockStatus.color }}">
  7.                                             {{ stockStatus.label }}
  8.                                         </span>
  9.                                     </div>
  10.                                     <div class="text-xs text-gray-500 mt-1">
  11.                                         Min: {{ article.minStock }} | Max: {{ article.maxStock }}
  1.                 // line 300
  2.                 yield $this->env->getRuntime('Twig\Runtime\EscaperRuntime')->escape(CoreExtension::getAttribute($this->env$this->source$context["article"], "currentStock", [], "any"falsefalsefalse300), "html"nulltrue);
  3.                 yield "</span>
  4.                                         <span class=\"inline-flex items-center px-2 py-1 rounded-full text-xs font-medium ";
  5.                 // line 301
  6.                 yield $this->env->getRuntime('Twig\Runtime\EscaperRuntime')->escape(CoreExtension::getAttribute($this->env$this->source, (isset($context["stockStatus"]) || array_key_exists("stockStatus"$context) ? $context["stockStatus"] : (function () { throw new RuntimeError('Variable "stockStatus" does not exist.'301$this->source); })()), "color", [], "any"falsefalsefalse301), "html"nulltrue);
  7.                 yield "\">
  8.                                             ";
  9.                 // line 302
  10.                 yield $this->env->getRuntime('Twig\Runtime\EscaperRuntime')->escape(CoreExtension::getAttribute($this->env$this->source, (isset($context["stockStatus"]) || array_key_exists("stockStatus"$context) ? $context["stockStatus"] : (function () { throw new RuntimeError('Variable "stockStatus" does not exist.'302$this->source); })()), "label", [], "any"falsefalsefalse302), "html"nulltrue);
  11.                 yield "
in vendor/twig/twig/src/Template.php -> block_body (line 446)
  1.             throw new \LogicException('A block must be a method on a \Twig\Template instance.');
  2.         }
  3.         if (null !== $template) {
  4.             try {
  5.                 yield from $template->$block($context$blocks);
  6.             } catch (Error $e) {
  7.                 if (!$e->getSourceContext()) {
  8.                     $e->setSourceContext($template->getSourceContext());
  9.                 }
  1.             <!-- Contenu principal -->
  2.             <main class=\"flex-1 overflow-auto\">
  3.                 <div class=\"p-6\">
  4.                     ";
  5.         // line 92
  6.         yield from $this->unwrap()->yieldBlock('body'$context$blocks);
  7.         // line 93
  8.         yield "                </div>
  9.             </main>
  10.         </div>
in vendor/twig/twig/src/Template.php -> doDisplay (line 402)
  1.     {
  2.         $context += $this->env->getGlobals();
  3.         $blocks array_merge($this->blocks$blocks);
  4.         try {
  5.             yield from $this->doDisplay($context$blocks);
  6.         } catch (Error $e) {
  7.             if (!$e->getSourceContext()) {
  8.                 $e->setSourceContext($this->getSourceContext());
  9.             }
  1.         $__internal_6f47bbe9983af81f1e7450e9a3e3768f $this->extensions["Symfony\\Bridge\\Twig\\Extension\\ProfilerExtension"];
  2.         $__internal_6f47bbe9983af81f1e7450e9a3e3768f->enter($__internal_6f47bbe9983af81f1e7450e9a3e3768f_prof = new \Twig\Profiler\Profile($this->getTemplateName(), "template""article/index.html.twig"));
  3.         $this->parent $this->load("base.html.twig"1);
  4.         yield from $this->parent->unwrap()->yield($contextarray_merge($this->blocks$blocks));
  5.         
  6.         $__internal_5a27a8ba21ca79b61932376b2fa922d2->leave($__internal_5a27a8ba21ca79b61932376b2fa922d2_prof);
  7.         
  8.         $__internal_6f47bbe9983af81f1e7450e9a3e3768f->leave($__internal_6f47bbe9983af81f1e7450e9a3e3768f_prof);
in vendor/twig/twig/src/Template.php -> doDisplay (line 402)
  1.     {
  2.         $context += $this->env->getGlobals();
  3.         $blocks array_merge($this->blocks$blocks);
  4.         try {
  5.             yield from $this->doDisplay($context$blocks);
  6.         } catch (Error $e) {
  7.             if (!$e->getSourceContext()) {
  8.                 $e->setSourceContext($this->getSourceContext());
  9.             }
  1.         return $this->blocks;
  2.     }
  3.     public function display(array $context, array $blocks = []): void
  4.     {
  5.         foreach ($this->yield($context$blocks) as $data) {
  6.             echo $data;
  7.         }
  8.     }
  9.     public function render(array $context): string
in vendor/twig/twig/src/Template.php -> display (line 373)
  1.                 ob_start();
  2.             } else {
  3.                 ob_start(function () { return ''; });
  4.             }
  5.             try {
  6.                 $this->display($context);
  7.             } catch (\Throwable $e) {
  8.                 while (ob_get_level() > $level) {
  9.                     ob_end_clean();
  10.                 }
  1.         yield from $this->template->yieldBlock($name$context);
  2.     }
  3.     public function render(array $context = []): string
  4.     {
  5.         return $this->template->render($context);
  6.     }
  7.     /**
  8.      * @return void
  9.      */
  1.      * @throws SyntaxError  When an error occurred during compilation
  2.      * @throws RuntimeError When an error occurred during rendering
  3.      */
  4.     public function render($name, array $context = []): string
  5.     {
  6.         return $this->load($name)->render($context);
  7.     }
  8.     /**
  9.      * Displays a template.
  10.      *
  1.         if (null !== $block) {
  2.             return $this->container->get('twig')->load($view)->renderBlock($block$parameters);
  3.         }
  4.         return $this->container->get('twig')->render($view$parameters);
  5.     }
  6.     private function doRender(string $view, ?string $block, array $parameters, ?Response $responsestring $method): Response
  7.     {
  8.         $content $this->doRenderView($view$block$parameters$method);
  1.         return $this->container->get('twig')->render($view$parameters);
  2.     }
  3.     private function doRender(string $view, ?string $block, array $parameters, ?Response $responsestring $method): Response
  4.     {
  5.         $content $this->doRenderView($view$block$parameters$method);
  6.         $response ??= new Response();
  7.         if (200 === $response->getStatusCode()) {
  8.             foreach ($parameters as $v) {
  9.                 if ($v instanceof FormInterface && $v->isSubmitted() && !$v->isValid()) {
  1.      * If an invalid form is found in the list of parameters, a 422 status code is returned.
  2.      * Forms found in parameters are auto-cast to form views.
  3.      */
  4.     protected function render(string $view, array $parameters = [], ?Response $response null): Response
  5.     {
  6.         return $this->doRender($viewnull$parameters$response__FUNCTION__);
  7.     }
  8.     /**
  9.      * Renders a block in a view.
  10.      *
AbstractController->render() in src/Controller/ArticleController.php (line 29)
  1.         $stockLevelFilter $request->query->get('stock_level''all');
  2.         $articles $articleRepository->findWithFilters($searchTerm$categoryFilter$stockLevelFilter);
  3.         $stats $articleRepository->getStockStatistics();
  4.         return $this->render('article/index.html.twig', [
  5.             'articles' => $articles,
  6.             'stats' => $stats,
  7.             'filters' => [
  8.                 'search' => $searchTerm,
  9.                 'category' => $categoryFilter,
  1.         $this->dispatcher->dispatch($eventKernelEvents::CONTROLLER_ARGUMENTS);
  2.         $controller $event->getController();
  3.         $arguments $event->getArguments();
  4.         // call controller
  5.         $response $controller(...$arguments);
  6.         // view
  7.         if (!$response instanceof Response) {
  8.             $event = new ViewEvent($this$request$type$response$event);
  9.             $this->dispatcher->dispatch($eventKernelEvents::VIEW);
  1.         $request->headers->set('X-Php-Ob-Level', (string) ob_get_level());
  2.         $this->requestStack->push($request);
  3.         $response null;
  4.         try {
  5.             return $response $this->handleRaw($request$type);
  6.         } catch (\Throwable $e) {
  7.             if ($e instanceof \Error && !$this->handleAllThrowables) {
  8.                 throw $e;
  9.             }
  1.         $this->boot();
  2.         ++$this->requestStackSize;
  3.         $this->resetServices true;
  4.         try {
  5.             return $this->getHttpKernel()->handle($request$type$catch);
  6.         } finally {
  7.             --$this->requestStackSize;
  8.         }
  9.     }
  1.     ) {
  2.     }
  3.     public function run(): int
  4.     {
  5.         $response $this->kernel->handle($this->request);
  6.         if (Kernel::VERSION_ID >= 60400) {
  7.             $response->send(false);
  8.             if (\function_exists('fastcgi_finish_request') && !$this->debug) {
in vendor/autoload_runtime.php -> run (line 29)
  1. $app $app(...$args);
  2. exit(
  3.     $runtime
  4.         ->getRunner($app)
  5.         ->run()
  6. );
require_once('/var/www/vhosts/farahtech.ma/garage/vendor/autoload_runtime.php') in public/index.php (line 5)
  1. <?php
  2. use App\Kernel;
  3. require_once dirname(__DIR__).'/vendor/autoload_runtime.php';
  4. return function (array $context) {
  5.     return new Kernel($context['APP_ENV'], (bool) $context['APP_DEBUG']);
  6. };

Logs

Level Channel Message
INFO 05:46:03 request Matched route "_profiler".
{
    "route": "_profiler",
    "route_parameters": {
        "_route": "_profiler",
        "_controller": "web_profiler.controller.profiler::panelAction",
        "token": "230382"
    },
    "request_uri": "https://garage.farahtech.ma/_profiler/230382?panel=exception&type=request",
    "method": "GET"
}
DEBUG 05:46:03 event Notified event "kernel.request" to listener "Symfony\Component\HttpKernel\EventListener\DebugHandlersListener::configure".
{
    "event": "kernel.request",
    "listener": "Symfony\\Component\\HttpKernel\\EventListener\\DebugHandlersListener::configure"
}
DEBUG 05:46:03 event Notified event "kernel.request" to listener "Symfony\UX\Turbo\Request\RequestListener::__invoke".
{
    "event": "kernel.request",
    "listener": "Symfony\\UX\\Turbo\\Request\\RequestListener::__invoke"
}
DEBUG 05:46:03 event Notified event "kernel.request" to listener "Symfony\Component\HttpKernel\EventListener\ValidateRequestListener::onKernelRequest".
{
    "event": "kernel.request",
    "listener": "Symfony\\Component\\HttpKernel\\EventListener\\ValidateRequestListener::onKernelRequest"
}
DEBUG 05:46:03 event Notified event "kernel.request" to listener "Symfony\Bridge\Doctrine\Middleware\IdleConnection\Listener::onKernelRequest".
{
    "event": "kernel.request",
    "listener": "Symfony\\Bridge\\Doctrine\\Middleware\\IdleConnection\\Listener::onKernelRequest"
}
DEBUG 05:46:03 event Notified event "kernel.request" to listener "Symfony\Component\HttpKernel\EventListener\SessionListener::onKernelRequest".
{
    "event": "kernel.request",
    "listener": "Symfony\\Component\\HttpKernel\\EventListener\\SessionListener::onKernelRequest"
}
DEBUG 05:46:03 event Notified event "kernel.request" to listener "Symfony\Component\HttpKernel\EventListener\LocaleListener::setDefaultLocale".
{
    "event": "kernel.request",
    "listener": "Symfony\\Component\\HttpKernel\\EventListener\\LocaleListener::setDefaultLocale"
}
DEBUG 05:46:03 event Notified event "kernel.request" to listener "Symfony\Component\AssetMapper\AssetMapperDevServerSubscriber::onKernelRequest".
{
    "event": "kernel.request",
    "listener": "Symfony\\Component\\AssetMapper\\AssetMapperDevServerSubscriber::onKernelRequest"
}
DEBUG 05:46:03 event Notified event "kernel.request" to listener "Symfony\Component\HttpKernel\EventListener\RouterListener::onKernelRequest".
{
    "event": "kernel.request",
    "listener": "Symfony\\Component\\HttpKernel\\EventListener\\RouterListener::onKernelRequest"
}
DEBUG 05:46:03 event Notified event "kernel.request" to listener "Symfony\Component\HttpKernel\EventListener\LocaleListener::onKernelRequest".
{
    "event": "kernel.request",
    "listener": "Symfony\\Component\\HttpKernel\\EventListener\\LocaleListener::onKernelRequest"
}
DEBUG 05:46:03 event Notified event "kernel.request" to listener "Symfony\Component\HttpKernel\EventListener\LocaleAwareListener::onKernelRequest".
{
    "event": "kernel.request",
    "listener": "Symfony\\Component\\HttpKernel\\EventListener\\LocaleAwareListener::onKernelRequest"
}
DEBUG 05:46:03 event Notified event "kernel.request" to listener "Symfony\Bundle\SecurityBundle\Debug\TraceableFirewallListener::configureLogoutUrlGenerator".
{
    "event": "kernel.request",
    "listener": "Symfony\\Bundle\\SecurityBundle\\Debug\\TraceableFirewallListener::configureLogoutUrlGenerator"
}
DEBUG 05:46:03 event Notified event "kernel.request" to listener "Symfony\Bundle\SecurityBundle\Debug\TraceableFirewallListener::onKernelRequest".
{
    "event": "kernel.request",
    "listener": "Symfony\\Bundle\\SecurityBundle\\Debug\\TraceableFirewallListener::onKernelRequest"
}
DEBUG 05:46:03 event Notified event "kernel.request" to listener "Knp\Bundle\PaginatorBundle\Subscriber\SlidingPaginationSubscriber::onKernelRequest".
{
    "event": "kernel.request",
    "listener": "Knp\\Bundle\\PaginatorBundle\\Subscriber\\SlidingPaginationSubscriber::onKernelRequest"
}
DEBUG 05:46:03 event Notified event "kernel.controller" to listener "Symfony\Bundle\FrameworkBundle\DataCollector\RouterDataCollector::onKernelController".
{
    "event": "kernel.controller",
    "listener": "Symfony\\Bundle\\FrameworkBundle\\DataCollector\\RouterDataCollector::onKernelController"
}
DEBUG 05:46:03 event Notified event "kernel.controller" to listener "Symfony\Component\HttpKernel\DataCollector\RequestDataCollector::onKernelController".
{
    "event": "kernel.controller",
    "listener": "Symfony\\Component\\HttpKernel\\DataCollector\\RequestDataCollector::onKernelController"
}
DEBUG 05:46:03 event Notified event "kernel.controller_arguments" to listener "Symfony\Component\Security\Http\EventListener\IsCsrfTokenValidAttributeListener::onKernelControllerArguments".
{
    "event": "kernel.controller_arguments",
    "listener": "Symfony\\Component\\Security\\Http\\EventListener\\IsCsrfTokenValidAttributeListener::onKernelControllerArguments"
}
DEBUG 05:46:03 event Notified event "kernel.controller_arguments" to listener "Symfony\Component\Security\Http\EventListener\IsGrantedAttributeListener::onKernelControllerArguments".
{
    "event": "kernel.controller_arguments",
    "listener": "Symfony\\Component\\Security\\Http\\EventListener\\IsGrantedAttributeListener::onKernelControllerArguments"
}
DEBUG 05:46:03 event Notified event "kernel.controller_arguments" to listener "Symfony\Component\HttpKernel\EventListener\CacheAttributeListener::onKernelControllerArguments".
{
    "event": "kernel.controller_arguments",
    "listener": "Symfony\\Component\\HttpKernel\\EventListener\\CacheAttributeListener::onKernelControllerArguments"
}
DEBUG 05:46:03 event Notified event "kernel.controller_arguments" to listener "Container6xBjgVf\RequestPayloadValueResolverGhost01ca9cc::onKernelControllerArguments".
{
    "event": "kernel.controller_arguments",
    "listener": "Container6xBjgVf\\RequestPayloadValueResolverGhost01ca9cc::onKernelControllerArguments"
}
DEBUG 05:46:03 event Notified event "kernel.controller_arguments" to listener "Symfony\Component\HttpKernel\EventListener\ErrorListener::onControllerArguments".
{
    "event": "kernel.controller_arguments",
    "listener": "Symfony\\Component\\HttpKernel\\EventListener\\ErrorListener::onControllerArguments"
}

Stack Trace

RuntimeError
Twig\Error\RuntimeError:
Impossible to access an attribute ("color") on a string variable ("out") in "article/index.html.twig" at line 301.

  at templates/article/index.html.twig:301
  at Twig\Extension\CoreExtension::getAttribute()
     (var/cache/dev/twig/f3/f3224bec76d12af3508a51dcedda6492.php:494)
  at __TwigTemplate_922d71cccb2dd8c98c1b94fecbe3c5e0->block_body()
     (vendor/twig/twig/src/Template.php:446)
  at Twig\Template->yieldBlock()
     (var/cache/dev/twig/a7/a7779046fbe976a001c8020942216064.php:177)
  at __TwigTemplate_4a4c28ab13324a70cd0cca486178722d->doDisplay()
     (vendor/twig/twig/src/Template.php:402)
  at Twig\Template->yield()
     (var/cache/dev/twig/f3/f3224bec76d12af3508a51dcedda6492.php:54)
  at __TwigTemplate_922d71cccb2dd8c98c1b94fecbe3c5e0->doDisplay()
     (vendor/twig/twig/src/Template.php:402)
  at Twig\Template->yield()
     (vendor/twig/twig/src/Template.php:358)
  at Twig\Template->display()
     (vendor/twig/twig/src/Template.php:373)
  at Twig\Template->render()
     (vendor/twig/twig/src/TemplateWrapper.php:51)
  at Twig\TemplateWrapper->render()
     (vendor/twig/twig/src/Environment.php:333)
  at Twig\Environment->render()
     (vendor/symfony/framework-bundle/Controller/AbstractController.php:459)
  at Symfony\Bundle\FrameworkBundle\Controller\AbstractController->doRenderView()
     (vendor/symfony/framework-bundle/Controller/AbstractController.php:464)
  at Symfony\Bundle\FrameworkBundle\Controller\AbstractController->doRender()
     (vendor/symfony/framework-bundle/Controller/AbstractController.php:278)
  at Symfony\Bundle\FrameworkBundle\Controller\AbstractController->render()
     (src/Controller/ArticleController.php:29)
  at App\Controller\ArticleController->index()
     (vendor/symfony/http-kernel/HttpKernel.php:183)
  at Symfony\Component\HttpKernel\HttpKernel->handleRaw()
     (vendor/symfony/http-kernel/HttpKernel.php:76)
  at Symfony\Component\HttpKernel\HttpKernel->handle()
     (vendor/symfony/http-kernel/Kernel.php:182)
  at Symfony\Component\HttpKernel\Kernel->handle()
     (vendor/symfony/runtime/Runner/Symfony/HttpKernelRunner.php:35)
  at Symfony\Component\Runtime\Runner\Symfony\HttpKernelRunner->run()
     (vendor/autoload_runtime.php:29)
  at require_once('/var/www/vhosts/farahtech.ma/garage/vendor/autoload_runtime.php')
     (public/index.php:5)