dga_feedback-2.0.0/src/Plugin/Block/DgaFeedbackBlock.php
src/Plugin/Block/DgaFeedbackBlock.php
<?php
namespace Drupal\dga_feedback\Plugin\Block;
use Drupal\Core\Block\BlockBase;
use Drupal\Core\Plugin\ContainerFactoryPluginInterface;
use Drupal\dga_feedback\Service\DgaFeedbackService;
use Drupal\node\Entity\Node;
use Symfony\Component\DependencyInjection\ContainerInterface;
/**
* Provides a DGA Feedback widget block.
*
* @Block(
* id = "dga_feedback_block",
* admin_label = @Translation("DGA Feedback Widget"),
* category = @Translation("Custom")
* )
*/
class DgaFeedbackBlock extends BlockBase implements ContainerFactoryPluginInterface {
/**
* The feedback service.
*
* @var \Drupal\dga_feedback\Service\DgaFeedbackService
*/
protected $feedbackService;
/**
* Constructs a DgaFeedbackBlock object.
*
* @param array $configuration
* A configuration array containing information about the plugin instance.
* @param string $plugin_id
* The plugin_id for the plugin instance.
* @param mixed $plugin_definition
* The plugin implementation definition.
* @param \Drupal\dga_feedback\Service\DgaFeedbackService $feedback_service
* The feedback service.
*/
public function __construct(array $configuration, $plugin_id, $plugin_definition, DgaFeedbackService $feedback_service) {
parent::__construct($configuration, $plugin_id, $plugin_definition);
$this->feedbackService = $feedback_service;
}
/**
* {@inheritdoc}
*/
public static function create(ContainerInterface $container, array $configuration, $plugin_id, $plugin_definition) {
return new static(
$configuration,
$plugin_id,
$plugin_definition,
$container->get('dga_feedback.service')
);
}
/**
* {@inheritdoc}
*/
public function build() {
// Get current URL path - use canonical path, not alias, for consistency.
$current_path = \Drupal::service('path.current')->getPath();
// Get the current request to extract the actual URL path
$request = \Drupal::request();
$request_path = $request->getPathInfo();
// Get the alias
$url_alias = \Drupal::service('path_alias.manager')->getAliasByPath($current_path);
// IMPORTANT: Use alias (without language prefix) for consistency
if ($url_alias !== $current_path && $url_alias !== '/') {
$url = rtrim($url_alias, '/');
} else {
// If no alias, strip language prefix from request path
$url = $request_path;
if (preg_match('#^/[a-z]{2}/(.+)$#', $url, $matches)) {
$url = '/' . $matches[1];
}
$url = rtrim($url, '/') ?: '/';
}
// Ensure we don't have language prefix in the final URL
if (preg_match('#^/[a-z]{2}/#', $url)) {
$url = preg_replace('#^/[a-z]{2}#', '', $url);
$url = rtrim($url, '/') ?: '/';
}
// Try to get entity context if available.
$entity_type = NULL;
$entity_id = NULL;
$route_match = \Drupal::routeMatch();
// Check if we're on a node page.
$node = $route_match->getParameter('node');
if ($node instanceof Node) {
$entity_type = 'node';
$entity_id = $node->id();
if ($entity_id > 0) {
$stats = $this->feedbackService->getStatistics($entity_type, $entity_id, $url);
} else {
$stats = $this->feedbackService->getStatisticsByUrl($url);
}
}
else {
// Fallback to URL-based statistics.
$stats = $this->feedbackService->getStatisticsByUrl($url);
}
// Format the yes percentage
$yes_percentage = $stats['yes_percentage'] > 0 ? number_format($stats['yes_percentage'], 0, '.', '') : '0';
$total_count = (int) $stats['total_count'];
// Ensure count is always a number (not string).
$total_count = max(0, $total_count);
// Load configuration for text strings.
$config = \Drupal::config('dga_feedback.settings');
// Determine current language.
$language_manager = \Drupal::languageManager();
$current_lang = $language_manager->getCurrentLanguage()->getId();
$is_arabic = ($current_lang === 'ar');
$getTranslation = function ($base_key, $default_en, $default_ar = NULL) use ($config, $is_arabic) {
$value_en = $config->get($base_key . '_en');
$value_ar = $config->get($base_key . '_ar');
if ($is_arabic) {
if (!empty($value_ar)) {
return $value_ar;
}
if (!empty($value_en)) {
return $value_en;
}
return $default_ar ?? $default_en;
}
if (!empty($value_en)) {
return $value_en;
}
return $default_en;
};
$reasons_yes_raw = $getTranslation(
'reasons_yes',
"Content is relevant\nIt was well written\nThe layout made it easy to read\nSomething else",
"المحتوى ذو صلة\nكان مكتوبًا بشكل جيد\nجعل التخطيط القراءة سهلة\nشيء آخر"
);
$reasons_no_raw = $getTranslation(
'reasons_no',
"Content is not relevant\nContent is not accurate\nContent is too long\nSomething else",
"المحتوى غير ذي صلة\nالمحتوى غير دقيق\nالمحتوى طويل جدًا\nشيء آخر"
);
$reasons_yes_translated = [];
$reasons_no_translated = [];
foreach (explode("\n", $reasons_yes_raw) as $reason) {
$reason = trim($reason);
if ($reason !== '') {
$reasons_yes_translated[] = $reason;
}
}
foreach (explode("\n", $reasons_no_raw) as $reason) {
$reason = trim($reason);
if ($reason !== '') {
$reasons_no_translated[] = $reason;
}
}
// Build render array.
$build = [
'#theme' => 'dga_feedback_widget',
'#yes_percentage' => $yes_percentage,
'#total_count' => $total_count,
'#url' => $url,
'#entity_type' => $entity_type,
'#entity_id' => $entity_id,
'#texts' => [
'question_text' => $getTranslation('question_text', 'Was this page useful?', 'هل كانت هذه الصفحة مفيدة؟'),
'yes_button_text' => $getTranslation('yes_button_text', 'Yes', 'نعم'),
'no_button_text' => $getTranslation('no_button_text', 'No', 'لا'),
'stats_text_template' => $getTranslation('stats_text_template', '@percentage% of users said Yes from @count Feedbacks', '@percentage% من المستخدمين قالوا نعم من @count تعليق'),
'close_button_text' => $getTranslation('close_button_text', 'Close', 'إغلاق'),
'reasons_title' => $getTranslation('reasons_title', 'Please tell us why', 'يرجى إخبارنا بالسبب'),
'reasons_instruction' => $getTranslation('reasons_instruction', 'you can select multiple options', 'يمكنك اختيار خيارات متعددة'),
'feedback_label' => $getTranslation('feedback_label', 'Feedback', 'التعليقات'),
'feedback_placeholder' => $getTranslation('feedback_placeholder', 'text placeholder', 'نص توضيحي'),
'gender_label' => $getTranslation('gender_label', "I'm", 'أنا'),
'gender_male' => $getTranslation('gender_male', 'Male', 'ذكر'),
'gender_female' => $getTranslation('gender_female', 'Female', 'أنثى'),
'submit_button_text' => $getTranslation('submit_button_text', 'Submit', 'إرسال'),
'submitted_success_text' => $getTranslation('submitted_success_text', 'Your feedback is submitted!', 'تم إرسال تعليقك!'),
'reasons_yes' => implode("\n", $reasons_yes_translated),
'reasons_no' => implode("\n", $reasons_no_translated),
'validation_yes_no_required' => $getTranslation('validation_yes_no_required', 'Please select Yes or No first.', 'يرجى اختيار نعم أو لا أولاً.'),
'validation_reason_required' => $getTranslation('validation_reason_required', 'Please select at least one reason', 'يرجى اختيار سبب واحد على الأقل'),
'validation_reason_invalid' => $getTranslation('validation_reason_invalid', 'At least one valid reason must be selected.', 'يجب اختيار سبب واحد صالح على الأقل.'),
'validation_feedback_required' => $getTranslation('validation_feedback_required', 'Please provide feedback text', 'يرجى تقديم نص التعليق'),
'validation_gender_required' => $getTranslation('validation_gender_required', 'Please select your gender', 'يرجى اختيار جنسك'),
'validation_submission_failed' => $getTranslation('validation_submission_failed', 'Submission failed. Please try again.', 'فشل الإرسال. يرجى المحاولة مرة أخرى.'),
'validation_unknown_error' => $getTranslation('validation_unknown_error', 'Unknown error', 'خطأ غير معروف'),
'button_submitting_text' => $getTranslation('button_submitting_text', 'Submitting...', 'جاري الإرسال...'),
],
'#attached' => [
'library' => [
'dga_feedback/feedback_widget',
],
'drupalSettings' => [
'dgaFeedback' => [
'submitUrl' => \Drupal\Core\Url::fromRoute('dga_feedback.submit')->toString(),
'statsUrl' => \Drupal\Core\Url::fromRoute('dga_feedback.stats')->toString(),
'refreshBlockUrl' => \Drupal\Core\Url::fromRoute('dga_feedback.refresh_block')->toString(),
'questionText' => $getTranslation('question_text', 'Was this page useful?', 'هل كانت هذه الصفحة مفيدة؟'),
'submittedSuccessText' => $getTranslation('submitted_success_text', 'Your feedback is submitted!', 'تم إرسال تعليقك!'),
'errorMessage' => $getTranslation('validation_submission_failed', 'Submission failed. Please try again.', 'فشل الإرسال. يرجى المحاولة مرة أخرى.'),
'unknownMessage' => $getTranslation('validation_unknown_error', 'Unknown error', 'خطأ غير معروف'),
'buttonSubmittingText' => $getTranslation('button_submitting_text', 'Submitting...', 'جاري الإرسال...'),
'apiMessages' => [
'methodNotAllowed' => $getTranslation('api_method_not_allowed', 'Method not allowed. Use POST.', 'الطريقة غير مسموحة. استخدم POST.'),
'invalidJson' => $getTranslation('api_invalid_json', 'Invalid JSON data', 'بيانات JSON غير صالحة'),
'invalidUseful' => $getTranslation('api_invalid_useful', 'is_useful must be "yes" or "no"', 'يجب أن يكون is_useful "yes" أو "no"'),
'rateLimit' => $getTranslation('api_rate_limit', 'Too many submissions. Please try again later.', 'عدد كبير جدًا من الإرسالات. يرجى المحاولة مرة أخرى لاحقًا.'),
'saveFailed' => $getTranslation('api_save_failed', 'Failed to save feedback.', 'فشل حفظ التعليق.'),
'success' => $getTranslation('api_success_message', 'Thank you for your feedback!', 'شكرًا لك على تعليقك!'),
],
'refreshDelay' => $config->get('refresh_delay') ?? 3000,
],
],
],
'#cache' => [
'max-age' => 0, // Disable cache for dynamic content.
'contexts' => [
'url.path',
'route',
'user.roles:anonymous',
],
'tags' => [
'dga_feedback:submissions',
'config:dga_feedback.settings',
],
],
];
return $build;
}
}
