189 lines
6.6 KiB
PHP
189 lines
6.6 KiB
PHP
<?php
|
|
|
|
declare(strict_types=1);
|
|
|
|
use app\common\service\qywx\MediaChannelService;
|
|
use think\facade\Db;
|
|
|
|
require dirname(__DIR__) . '/vendor/autoload.php';
|
|
|
|
$mergeMethod = new ReflectionMethod(MediaChannelService::class, 'mergeConfiguredChannelsWithTags');
|
|
$mergeMethod->setAccessible(true);
|
|
$scanUpdateFields = (new ReflectionClass(MediaChannelService::class))
|
|
->getReflectionConstant('SCAN_DUPLICATE_UPDATE_FIELDS')
|
|
?->getValue();
|
|
if (!is_array($scanUpdateFields)
|
|
|| array_intersect(['channel_name', 'source_tag_name', 'status'], $scanUpdateFields) !== []) {
|
|
throw new RuntimeException('Channel scan would overwrite rename aliases, manual labels, or disabled status');
|
|
}
|
|
|
|
$configuredRows = [
|
|
[
|
|
'id' => 1,
|
|
'channel_code' => 'stable-a',
|
|
'channel_name' => 'Old tag name',
|
|
'source_tag_id' => 'tag-a',
|
|
'source_tag_name' => 'Old tag name',
|
|
'source_group_name' => 'Old group',
|
|
'status' => 1,
|
|
],
|
|
[
|
|
'id' => 2,
|
|
'channel_code' => 'manual-name',
|
|
'channel_name' => 'Manual campaign label',
|
|
'source_tag_id' => 'tag-manual',
|
|
'source_tag_name' => 'Old manual tag',
|
|
'source_group_name' => 'Old group',
|
|
'status' => 1,
|
|
],
|
|
[
|
|
'id' => 3,
|
|
'channel_code' => 'disabled-tag',
|
|
'channel_name' => 'Disabled tag',
|
|
'source_tag_id' => 'tag-disabled',
|
|
'source_tag_name' => 'Disabled tag',
|
|
'source_group_name' => 'Group',
|
|
'status' => 0,
|
|
],
|
|
[
|
|
'id' => 4,
|
|
'channel_code' => 'legacy-name-only',
|
|
'channel_name' => 'Legacy name-only channel',
|
|
'source_tag_id' => '',
|
|
'source_tag_name' => 'Legacy name-only channel',
|
|
'source_group_name' => 'Legacy',
|
|
'status' => 1,
|
|
],
|
|
];
|
|
|
|
$tagRows = [
|
|
[
|
|
'source_tag_id' => 'tag-a',
|
|
'source_tag_name' => 'Renamed tag',
|
|
'source_group_name' => 'New group',
|
|
],
|
|
[
|
|
'source_tag_id' => 'tag-manual',
|
|
'source_tag_name' => 'Renamed manual tag',
|
|
'source_group_name' => 'New group',
|
|
],
|
|
[
|
|
'source_tag_id' => 'tag-disabled',
|
|
'source_tag_name' => 'Disabled tag returned by relation table',
|
|
'source_group_name' => 'Group',
|
|
],
|
|
[
|
|
'source_tag_id' => 'tag-new',
|
|
'source_tag_name' => 'Newly discovered tag',
|
|
'source_group_name' => 'New group',
|
|
],
|
|
];
|
|
|
|
/** @var array<int, array<string, mixed>> $mergedRows */
|
|
$mergedRows = $mergeMethod->invoke(null, $configuredRows, $tagRows);
|
|
$byCode = [];
|
|
foreach ($mergedRows as $row) {
|
|
$byCode[(string) ($row['channel_code'] ?? '')] = $row;
|
|
}
|
|
|
|
$renamed = $byCode['stable-a'] ?? null;
|
|
if (!is_array($renamed)
|
|
|| ($renamed['channel_name'] ?? '') !== 'Renamed tag'
|
|
|| ($renamed['source_tag_name'] ?? '') !== 'Renamed tag'
|
|
|| ($renamed['source_group_name'] ?? '') !== 'New group'
|
|
|| ($renamed['legacy_channel_name'] ?? '') !== 'Old tag name'
|
|
|| ($renamed['legacy_source_tag_name'] ?? '') !== 'Old tag name') {
|
|
throw new RuntimeException('Automatic channel name was not refreshed with backward-compatible aliases');
|
|
}
|
|
|
|
$manual = $byCode['manual-name'] ?? null;
|
|
if (!is_array($manual)
|
|
|| ($manual['channel_name'] ?? '') !== 'Manual campaign label'
|
|
|| ($manual['source_tag_name'] ?? '') !== 'Renamed manual tag'
|
|
|| ($manual['legacy_source_tag_name'] ?? '') !== 'Old manual tag') {
|
|
throw new RuntimeException('Manual display name or refreshed tag metadata was not preserved');
|
|
}
|
|
|
|
if (isset($byCode['disabled-tag']) || isset($byCode['tag_tag-disabled'])) {
|
|
throw new RuntimeException('Explicitly disabled tag was reintroduced');
|
|
}
|
|
|
|
$newTag = $byCode['tag_tag-new'] ?? null;
|
|
if (!is_array($newTag)
|
|
|| ($newTag['channel_name'] ?? '') !== 'Newly discovered tag'
|
|
|| ($newTag['source_tag_id'] ?? '') !== 'tag-new') {
|
|
throw new RuntimeException('New relation-table tag was not added with a deterministic channel code');
|
|
}
|
|
|
|
if (!isset($byCode['legacy-name-only'])) {
|
|
throw new RuntimeException('Historical name-only channel was removed');
|
|
}
|
|
|
|
if (in_array('--integration', $argv, true)) {
|
|
$app = new think\App();
|
|
$app->initialize();
|
|
|
|
$loadTagsMethod = new ReflectionMethod(MediaChannelService::class, 'loadCurrentTagRows');
|
|
$loadTagsMethod->setAccessible(true);
|
|
$activeRowsMethod = new ReflectionMethod(MediaChannelService::class, 'getActiveChannelRows');
|
|
$activeRowsMethod->setAccessible(true);
|
|
|
|
$startedAt = microtime(true);
|
|
/** @var array<int, array<string, mixed>> $currentTags */
|
|
$currentTags = $loadTagsMethod->invoke(null, null);
|
|
/** @var array<int, array<string, mixed>> $activeRows */
|
|
$activeRows = $activeRowsMethod->invoke(null);
|
|
$options = MediaChannelService::getOptions();
|
|
$elapsedMs = round((microtime(true) - $startedAt) * 1000, 1);
|
|
|
|
$activeByTagId = [];
|
|
foreach ($activeRows as $row) {
|
|
$tagId = trim((string) ($row['source_tag_id'] ?? ''));
|
|
if ($tagId !== '') {
|
|
$activeByTagId[$tagId] = $row;
|
|
}
|
|
}
|
|
$disabledTagIds = array_fill_keys(array_map(
|
|
'strval',
|
|
Db::name('qywx_media_channel')
|
|
->where('status', 0)
|
|
->where('source_tag_id', '<>', '')
|
|
->column('source_tag_id')
|
|
), true);
|
|
|
|
foreach ($currentTags as $tag) {
|
|
$tagId = (string) ($tag['source_tag_id'] ?? '');
|
|
if ($tagId === '' || isset($disabledTagIds[$tagId])) {
|
|
continue;
|
|
}
|
|
$channel = $activeByTagId[$tagId] ?? null;
|
|
if (!is_array($channel)) {
|
|
throw new RuntimeException("Current relation-table tag {$tagId} is absent from channel options");
|
|
}
|
|
$currentName = (string) ($tag['source_tag_name'] ?? '');
|
|
if ($currentName !== '' && ($channel['source_tag_name'] ?? '') !== $currentName) {
|
|
throw new RuntimeException("Current tag name for {$tagId} was not refreshed");
|
|
}
|
|
}
|
|
|
|
if (count($options) !== count($activeRows)) {
|
|
throw new RuntimeException('Public option count differs from merged active channel count');
|
|
}
|
|
|
|
$matchingNames = array_values(array_map(
|
|
static fn (array $option): string => (string) ($option['name'] ?? ''),
|
|
array_filter(
|
|
$options,
|
|
static fn (array $option): bool => mb_strpos((string) ($option['name'] ?? ''), '4') !== false
|
|
)
|
|
));
|
|
echo json_encode([
|
|
'current_tag_count' => count($currentTags),
|
|
'channel_option_count' => count($options),
|
|
'elapsed_ms' => $elapsedMs,
|
|
'matching_4' => $matchingNames,
|
|
], JSON_UNESCAPED_UNICODE | JSON_UNESCAPED_SLASHES), "\n";
|
|
}
|
|
|
|
echo "MEDIA_CHANNEL_OPTIONS_MERGE_OK\n";
|