PluginProbe
ووسلام – همگام سازی ووکامرس و باسلام / 1.10.19
ووسلام – همگام سازی ووکامرس و باسلام v1.10.19
1.10.19 1.10.20 1.10.18 1.10.17 1.10.15 1.10.14 1.10.13 1.10.12 1.10.10 1.10.9 1.10.8 1.10.7 1.10.6 1.10.5 1.10.4 1.10.3 1.10.2 1.10.1 1.10.0 1.9.2 1.9.1 1.9.0 1.8.8 1.8.5 1.8.6 All 53 releases
sync-basalam / includes / Admin / Product / Data / Services / VideoService.php

VideoService.php in ووسلام – همگام سازی ووکامرس و باسلام 1.10.19, at includes/Admin/Product/Data/Services/VideoService.php

154 lines 4.9 KB
No matching file
Up and down to move Enter to open Esc to close
Raw Download Zip
1 <?php
2
3 namespace SyncBasalam\Admin\Product\Data\Services;
4
5 use SyncBasalam\Logger\Logger;
6 use SyncBasalam\Services\FileUploader;
7 use SyncBasalam\Services\Products\VideoSourceResolver;
8
9 defined('ABSPATH') || exit;
10
11 class VideoService
12 {
13 private $fileUploader;
14
15 public function __construct()
16 {
17 $this->fileUploader = new FileUploader();
18 }
19
20 public function getVideoFileId($product): ?int
21 {
22 $productId = (int) $product->get_id();
23 $rawValue = VideoSourceResolver::resolveValue($productId);
24
25 if ($rawValue === null) return null;
26
27 $sourceIdentity = $this->buildSourceIdentity($rawValue);
28 $filePath = $this->resolveLocalPath($rawValue);
29
30 if ($filePath === null) {
31 Logger::info('ویدیو �
32 حصول به‌صورت لوکال در دسترس نیست؛ آپلود به باسلا�
33 انجا�
34 ن�
35 ی‌شود.', [
36 'product_id' => $productId,
37 'raw_value' => $rawValue,
38 ]);
39 return null;
40 }
41
42 $existing = $this->getExistingVideo($sourceIdentity);
43 if ($existing) return (int) $existing['file_id'];
44
45 try {
46 $uploaded = $this->fileUploader->uploadVideo($filePath);
47 } catch (\Throwable $e) {
48 Logger::error('خطا در آپلود ویدیو �
49 حصول به باسلا�
50 : ' . $e->getMessage(), [
51 'product_id' => $productId,
52 'file_path' => $filePath,
53 ]);
54 return null;
55 }
56
57 if (!empty($uploaded['file_id'])) {
58 $this->storeVideoRecord($sourceIdentity, $uploaded);
59 return (int) $uploaded['file_id'];
60 }
61
62 return null;
63 }
64
65 private function resolveLocalPath(string $rawValue): ?string
66 {
67 if (ctype_digit($rawValue) || is_numeric($rawValue)) {
68 $attachmentId = (int) $rawValue;
69 $path = get_attached_file($attachmentId);
70 if ($path && file_exists($path)) return $path;
71
72 $url = wp_get_attachment_url($attachmentId);
73 return $url ?: null;
74 }
75
76 if (filter_var($rawValue, FILTER_VALIDATE_URL)) {
77 $homeUrl = home_url();
78 if (strpos($rawValue, $homeUrl) === 0) {
79 $attachmentId = attachment_url_to_postid($rawValue);
80 if ($attachmentId) {
81 $path = get_attached_file($attachmentId);
82 if ($path && file_exists($path)) return $path;
83 }
84 return $rawValue;
85 }
86
87 return null;
88 }
89
90 return null;
91 }
92
93 private function buildSourceIdentity(string $rawValue): string
94 {
95 if (ctype_digit($rawValue) || is_numeric($rawValue)) {
96 return 'attachment:' . (int) $rawValue;
97 }
98
99 return 'url:' . md5($rawValue);
100 }
101
102 private function getExistingVideo(string $sourceIdentity): ?array
103 {
104 global $wpdb;
105 $tableName = $wpdb->prefix . 'sync_basalam_uploaded_media';
106
107 // phpcs:ignore WordPress.DB.DirectDatabaseQuery.DirectQuery, WordPress.DB.DirectDatabaseQuery.NoCaching, PluginCheck.Security.DirectDB.UnescapedDBParameter -- Custom plugin table; identifier from $wpdb->prefix, not user input.
108 $result = $wpdb->get_row($wpdb->prepare(
109 "SELECT media_id AS file_id, media_url AS url, created_at
110 FROM $tableName
111 WHERE type = %s AND source_identity = %s",
112 'video',
113 $sourceIdentity
114 ), ARRAY_A);
115
116 if (!$result) return null;
117
118 $createdAt = strtotime($result['created_at']);
119 $now = current_time('timestamp');
120 $fourteenDays = 14 * DAY_IN_SECONDS;
121
122 if (($now - $createdAt) >= $fourteenDays) {
123 // phpcs:ignore WordPress.DB.DirectDatabaseQuery.DirectQuery, WordPress.DB.DirectDatabaseQuery.NoCaching -- Custom plugin table; no object cache for these operational queries.
124 $wpdb->delete(
125 $tableName,
126 ['type' => 'video', 'source_identity' => $sourceIdentity],
127 ['%s', '%s']
128 );
129 return null;
130 }
131
132 return $result;
133 }
134
135 private function storeVideoRecord(string $sourceIdentity, array $uploaded): void
136 {
137 global $wpdb;
138 $tableName = $wpdb->prefix . 'sync_basalam_uploaded_media';
139
140 // phpcs:ignore WordPress.DB.DirectDatabaseQuery.DirectQuery, WordPress.DB.DirectDatabaseQuery.NoCaching -- Custom plugin table; no object cache for these operational queries.
141 $wpdb->replace(
142 $tableName,
143 [
144 'type' => 'video',
145 'source_identity' => $sourceIdentity,
146 'media_id' => (int) $uploaded['file_id'],
147 'media_url' => $uploaded['url'] ?? '',
148 'created_at' => current_time('mysql'),
149 ],
150 ['%s', '%s', '%d', '%s', '%s']
151 );
152 }
153 }
154