Exceptions
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 }
in
templates/article/index.html.twig
(line 301)
</span></td><td class="py-4 px-6 text-center"><div class="flex items-center justify-center gap-2"><span class="text-lg font-bold text-gray-900">{{ article.currentStock }}</span><span class="inline-flex items-center px-2 py-1 rounded-full text-xs font-medium {{ stockStatus.color }}">{{ stockStatus.label }}</span></div><div class="text-xs text-gray-500 mt-1">Min: {{ article.minStock }} | Max: {{ article.maxStock }}
in
var/cache/dev/twig/f3/f3224bec76d12af3508a51dcedda6492.php
::
getAttribute
(line 494)
// line 300yield $this->env->getRuntime('Twig\Runtime\EscaperRuntime')->escape(CoreExtension::getAttribute($this->env, $this->source, $context["article"], "currentStock", [], "any", false, false, false, 300), "html", null, true);yield "</span><span class=\"inline-flex items-center px-2 py-1 rounded-full text-xs font-medium ";// line 301yield $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", false, false, false, 301), "html", null, true);yield "\">";// line 302yield $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", false, false, false, 302), "html", null, true);yield "
in
vendor/twig/twig/src/Template.php
->
block_body
(line 446)
throw new \LogicException('A block must be a method on a \Twig\Template instance.');}if (null !== $template) {try {yield from $template->$block($context, $blocks);} catch (Error $e) {if (!$e->getSourceContext()) {$e->setSourceContext($template->getSourceContext());}
in
var/cache/dev/twig/a7/a7779046fbe976a001c8020942216064.php
->
yieldBlock
(line 177)
<!-- Contenu principal --><main class=\"flex-1 overflow-auto\"><div class=\"p-6\">";// line 92yield from $this->unwrap()->yieldBlock('body', $context, $blocks);// line 93yield " </div></main></div>
in
vendor/twig/twig/src/Template.php
->
doDisplay
(line 402)
{$context += $this->env->getGlobals();$blocks = array_merge($this->blocks, $blocks);try {yield from $this->doDisplay($context, $blocks);} catch (Error $e) {if (!$e->getSourceContext()) {$e->setSourceContext($this->getSourceContext());}
in
var/cache/dev/twig/f3/f3224bec76d12af3508a51dcedda6492.php
->
yield
(line 54)
$__internal_6f47bbe9983af81f1e7450e9a3e3768f = $this->extensions["Symfony\\Bridge\\Twig\\Extension\\ProfilerExtension"];$__internal_6f47bbe9983af81f1e7450e9a3e3768f->enter($__internal_6f47bbe9983af81f1e7450e9a3e3768f_prof = new \Twig\Profiler\Profile($this->getTemplateName(), "template", "article/index.html.twig"));$this->parent = $this->load("base.html.twig", 1);yield from $this->parent->unwrap()->yield($context, array_merge($this->blocks, $blocks));$__internal_5a27a8ba21ca79b61932376b2fa922d2->leave($__internal_5a27a8ba21ca79b61932376b2fa922d2_prof);$__internal_6f47bbe9983af81f1e7450e9a3e3768f->leave($__internal_6f47bbe9983af81f1e7450e9a3e3768f_prof);
in
vendor/twig/twig/src/Template.php
->
doDisplay
(line 402)
{$context += $this->env->getGlobals();$blocks = array_merge($this->blocks, $blocks);try {yield from $this->doDisplay($context, $blocks);} catch (Error $e) {if (!$e->getSourceContext()) {$e->setSourceContext($this->getSourceContext());}
in
vendor/twig/twig/src/Template.php
->
yield
(line 358)
return $this->blocks;}public function display(array $context, array $blocks = []): void{foreach ($this->yield($context, $blocks) as $data) {echo $data;}}public function render(array $context): string
in
vendor/twig/twig/src/Template.php
->
display
(line 373)
ob_start();} else {ob_start(function () { return ''; });}try {$this->display($context);} catch (\Throwable $e) {while (ob_get_level() > $level) {ob_end_clean();}
in
vendor/twig/twig/src/TemplateWrapper.php
->
render
(line 51)
yield from $this->template->yieldBlock($name, $context);}public function render(array $context = []): string{return $this->template->render($context);}/*** @return void*/
in
vendor/twig/twig/src/Environment.php
->
render
(line 333)
* @throws SyntaxError When an error occurred during compilation* @throws RuntimeError When an error occurred during rendering*/public function render($name, array $context = []): string{return $this->load($name)->render($context);}/*** Displays a template.*
in
vendor/symfony/framework-bundle/Controller/AbstractController.php
->
render
(line 459)
if (null !== $block) {return $this->container->get('twig')->load($view)->renderBlock($block, $parameters);}return $this->container->get('twig')->render($view, $parameters);}private function doRender(string $view, ?string $block, array $parameters, ?Response $response, string $method): Response{$content = $this->doRenderView($view, $block, $parameters, $method);
in
vendor/symfony/framework-bundle/Controller/AbstractController.php
->
doRenderView
(line 464)
return $this->container->get('twig')->render($view, $parameters);}private function doRender(string $view, ?string $block, array $parameters, ?Response $response, string $method): Response{$content = $this->doRenderView($view, $block, $parameters, $method);$response ??= new Response();if (200 === $response->getStatusCode()) {foreach ($parameters as $v) {if ($v instanceof FormInterface && $v->isSubmitted() && !$v->isValid()) {
in
vendor/symfony/framework-bundle/Controller/AbstractController.php
->
doRender
(line 278)
* If an invalid form is found in the list of parameters, a 422 status code is returned.* Forms found in parameters are auto-cast to form views.*/protected function render(string $view, array $parameters = [], ?Response $response = null): Response{return $this->doRender($view, null, $parameters, $response, __FUNCTION__);}/*** Renders a block in a view.*
$stockLevelFilter = $request->query->get('stock_level', 'all');$articles = $articleRepository->findWithFilters($searchTerm, $categoryFilter, $stockLevelFilter);$stats = $articleRepository->getStockStatistics();return $this->render('article/index.html.twig', ['articles' => $articles,'stats' => $stats,'filters' => ['search' => $searchTerm,'category' => $categoryFilter,
in
vendor/symfony/http-kernel/HttpKernel.php
->
index
(line 183)
$this->dispatcher->dispatch($event, KernelEvents::CONTROLLER_ARGUMENTS);$controller = $event->getController();$arguments = $event->getArguments();// call controller$response = $controller(...$arguments);// viewif (!$response instanceof Response) {$event = new ViewEvent($this, $request, $type, $response, $event);$this->dispatcher->dispatch($event, KernelEvents::VIEW);
in
vendor/symfony/http-kernel/HttpKernel.php
->
handleRaw
(line 76)
$request->headers->set('X-Php-Ob-Level', (string) ob_get_level());$this->requestStack->push($request);$response = null;try {return $response = $this->handleRaw($request, $type);} catch (\Throwable $e) {if ($e instanceof \Error && !$this->handleAllThrowables) {throw $e;}
in
vendor/symfony/http-kernel/Kernel.php
->
handle
(line 182)
$this->boot();++$this->requestStackSize;$this->resetServices = true;try {return $this->getHttpKernel()->handle($request, $type, $catch);} finally {--$this->requestStackSize;}}
in
vendor/symfony/runtime/Runner/Symfony/HttpKernelRunner.php
->
handle
(line 35)
) {}public function run(): int{$response = $this->kernel->handle($this->request);if (Kernel::VERSION_ID >= 60400) {$response->send(false);if (\function_exists('fastcgi_finish_request') && !$this->debug) {
in
vendor/autoload_runtime.php
->
run
(line 29)
$app = $app(...$args);exit($runtime->getRunner($app)->run());
require_once('/var/www/vhosts/farahtech.ma/garage/vendor/autoload_runtime.php')
in
public/index.php
(line 5)
<?phpuse App\Kernel;require_once dirname(__DIR__).'/vendor/autoload_runtime.php';return function (array $context) {return new Kernel($context['APP_ENV'], (bool) $context['APP_DEBUG']);};
Logs
| Level | Channel | Message |
|---|---|---|
| INFO 03:14:45 | request |
Matched route "_profiler". {
"route": "_profiler",
"route_parameters": {
"_route": "_profiler",
"_controller": "web_profiler.controller.profiler::panelAction",
"token": "1cb18c"
},
"request_uri": "https://garage.farahtech.ma/_profiler/1cb18c?panel=exception&type=request",
"method": "GET"
}
|
| DEBUG 03:14:45 | event |
Notified event "kernel.request" to listener "Symfony\Component\HttpKernel\EventListener\DebugHandlersListener::configure". {
"event": "kernel.request",
"listener": "Symfony\\Component\\HttpKernel\\EventListener\\DebugHandlersListener::configure"
}
|
| DEBUG 03:14:45 | event |
Notified event "kernel.request" to listener "Symfony\UX\Turbo\Request\RequestListener::__invoke". {
"event": "kernel.request",
"listener": "Symfony\\UX\\Turbo\\Request\\RequestListener::__invoke"
}
|
| DEBUG 03:14:45 | event |
Notified event "kernel.request" to listener "Symfony\Component\HttpKernel\EventListener\ValidateRequestListener::onKernelRequest". {
"event": "kernel.request",
"listener": "Symfony\\Component\\HttpKernel\\EventListener\\ValidateRequestListener::onKernelRequest"
}
|
| DEBUG 03:14:45 | 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 03:14:45 | event |
Notified event "kernel.request" to listener "Symfony\Component\HttpKernel\EventListener\SessionListener::onKernelRequest". {
"event": "kernel.request",
"listener": "Symfony\\Component\\HttpKernel\\EventListener\\SessionListener::onKernelRequest"
}
|
| DEBUG 03:14:45 | event |
Notified event "kernel.request" to listener "Symfony\Component\HttpKernel\EventListener\LocaleListener::setDefaultLocale". {
"event": "kernel.request",
"listener": "Symfony\\Component\\HttpKernel\\EventListener\\LocaleListener::setDefaultLocale"
}
|
| DEBUG 03:14:45 | event |
Notified event "kernel.request" to listener "Symfony\Component\AssetMapper\AssetMapperDevServerSubscriber::onKernelRequest". {
"event": "kernel.request",
"listener": "Symfony\\Component\\AssetMapper\\AssetMapperDevServerSubscriber::onKernelRequest"
}
|
| DEBUG 03:14:45 | event |
Notified event "kernel.request" to listener "Symfony\Component\HttpKernel\EventListener\RouterListener::onKernelRequest". {
"event": "kernel.request",
"listener": "Symfony\\Component\\HttpKernel\\EventListener\\RouterListener::onKernelRequest"
}
|
| DEBUG 03:14:45 | event |
Notified event "kernel.request" to listener "Symfony\Component\HttpKernel\EventListener\LocaleListener::onKernelRequest". {
"event": "kernel.request",
"listener": "Symfony\\Component\\HttpKernel\\EventListener\\LocaleListener::onKernelRequest"
}
|
| DEBUG 03:14:45 | event |
Notified event "kernel.request" to listener "Symfony\Component\HttpKernel\EventListener\LocaleAwareListener::onKernelRequest". {
"event": "kernel.request",
"listener": "Symfony\\Component\\HttpKernel\\EventListener\\LocaleAwareListener::onKernelRequest"
}
|
| DEBUG 03:14:45 | event |
Notified event "kernel.request" to listener "Symfony\Bundle\SecurityBundle\Debug\TraceableFirewallListener::configureLogoutUrlGenerator". {
"event": "kernel.request",
"listener": "Symfony\\Bundle\\SecurityBundle\\Debug\\TraceableFirewallListener::configureLogoutUrlGenerator"
}
|
| DEBUG 03:14:45 | event |
Notified event "kernel.request" to listener "Symfony\Bundle\SecurityBundle\Debug\TraceableFirewallListener::onKernelRequest". {
"event": "kernel.request",
"listener": "Symfony\\Bundle\\SecurityBundle\\Debug\\TraceableFirewallListener::onKernelRequest"
}
|
| DEBUG 03:14:45 | event |
Notified event "kernel.request" to listener "Knp\Bundle\PaginatorBundle\Subscriber\SlidingPaginationSubscriber::onKernelRequest". {
"event": "kernel.request",
"listener": "Knp\\Bundle\\PaginatorBundle\\Subscriber\\SlidingPaginationSubscriber::onKernelRequest"
}
|
| DEBUG 03:14:45 | event |
Notified event "kernel.controller" to listener "Symfony\Bundle\FrameworkBundle\DataCollector\RouterDataCollector::onKernelController". {
"event": "kernel.controller",
"listener": "Symfony\\Bundle\\FrameworkBundle\\DataCollector\\RouterDataCollector::onKernelController"
}
|
| DEBUG 03:14:45 | event |
Notified event "kernel.controller" to listener "Symfony\Component\HttpKernel\DataCollector\RequestDataCollector::onKernelController". {
"event": "kernel.controller",
"listener": "Symfony\\Component\\HttpKernel\\DataCollector\\RequestDataCollector::onKernelController"
}
|
| DEBUG 03:14:45 | 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 03:14:45 | 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 03:14:45 | 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 03:14:45 | event |
Notified event "kernel.controller_arguments" to listener "Container6xBjgVf\RequestPayloadValueResolverGhost01ca9cc::onKernelControllerArguments". {
"event": "kernel.controller_arguments",
"listener": "Container6xBjgVf\\RequestPayloadValueResolverGhost01ca9cc::onKernelControllerArguments"
}
|
| DEBUG 03:14:45 | 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)
|