289 lines
No EOL
10 KiB
PHP
289 lines
No EOL
10 KiB
PHP
<?php
|
|
|
|
namespace Domains\Settings\Repositories;
|
|
|
|
use Domains\Settings\Models\Language;
|
|
use Illuminate\Database\Eloquent\Collection;
|
|
use Illuminate\Database\Eloquent\Builder;
|
|
use Illuminate\Support\Facades\DB;
|
|
use Illuminate\Pagination\LengthAwarePaginator;
|
|
|
|
class LanguageRepository
|
|
{
|
|
public function __construct(
|
|
private Language $model
|
|
) {}
|
|
|
|
/**
|
|
* Find languages available for route creation with optimized query
|
|
*/
|
|
public function findAvailableForRoutes(array $select = ['*']): Collection
|
|
{
|
|
return $this->model
|
|
->select($select)
|
|
->where('languages.is_active', true)
|
|
->whereExists(function ($query) {
|
|
$query->select(DB::raw(1))
|
|
->from('feed_languages')
|
|
->join('feeds', 'feeds.id', '=', 'feed_languages.feed_id')
|
|
->whereColumn('feed_languages.language_id', 'languages.id')
|
|
->where('feeds.is_active', true)
|
|
->where('feed_languages.is_active', true);
|
|
})
|
|
->whereExists(function ($query) {
|
|
$query->select(DB::raw(1))
|
|
->from('platform_channels')
|
|
->whereColumn('platform_channels.language_id', 'languages.id')
|
|
->where('platform_channels.is_active', true);
|
|
})
|
|
->orderBy('name')
|
|
->get();
|
|
}
|
|
|
|
/**
|
|
* Find feeds by language with efficient joins
|
|
*/
|
|
public function findFeedsByLanguage(
|
|
int $languageId,
|
|
?string $search = null,
|
|
array $select = ['feeds.*'],
|
|
int $perPage = 15
|
|
): LengthAwarePaginator {
|
|
$query = DB::table('feeds')
|
|
->join('feed_languages', 'feeds.id', '=', 'feed_languages.feed_id')
|
|
->where('feed_languages.language_id', $languageId)
|
|
->where('feeds.is_active', true)
|
|
->where('feed_languages.is_active', true)
|
|
->select($select);
|
|
|
|
if ($search) {
|
|
$query->where(function ($q) use ($search) {
|
|
$q->where('feeds.name', 'like', "%{$search}%")
|
|
->orWhere('feeds.url', 'like', "%{$search}%");
|
|
});
|
|
}
|
|
|
|
return $query->orderBy('feeds.name')
|
|
->paginate(min($perPage, 100));
|
|
}
|
|
|
|
/**
|
|
* Find channels by language with efficient joins
|
|
*/
|
|
public function findChannelsByLanguage(
|
|
int $languageId,
|
|
?string $search = null,
|
|
array $select = ['platform_channels.*'],
|
|
int $perPage = 15,
|
|
bool $withPlatformInstance = true
|
|
): LengthAwarePaginator {
|
|
$query = DB::table('platform_channels');
|
|
|
|
if ($withPlatformInstance) {
|
|
$query->join('platform_instances', 'platform_channels.platform_instance_id', '=', 'platform_instances.id')
|
|
->addSelect([
|
|
'platform_instances.id as platform_instance_id',
|
|
'platform_instances.name as platform_instance_name',
|
|
'platform_instances.url as platform_instance_url'
|
|
]);
|
|
}
|
|
|
|
$query->where('platform_channels.language_id', $languageId)
|
|
->where('platform_channels.is_active', true)
|
|
->select(array_merge($select, $withPlatformInstance ? [] : []));
|
|
|
|
if ($search) {
|
|
$query->where(function ($q) use ($search) {
|
|
$q->where('platform_channels.name', 'like', "%{$search}%")
|
|
->orWhere('platform_channels.display_name', 'like', "%{$search}%");
|
|
});
|
|
}
|
|
|
|
return $query->orderBy('platform_channels.name')
|
|
->paginate(min($perPage, 100));
|
|
}
|
|
|
|
/**
|
|
* Get language statistics with single optimized query
|
|
*/
|
|
public function getLanguageStatistics(int $languageId): object
|
|
{
|
|
return DB::selectOne("
|
|
SELECT
|
|
(SELECT COUNT(*) FROM feed_languages fl
|
|
JOIN feeds f ON f.id = fl.feed_id
|
|
WHERE fl.language_id = ? AND fl.is_active = 1 AND f.is_active = 1) as active_feeds_count,
|
|
(SELECT COUNT(*) FROM platform_channels pc
|
|
WHERE pc.language_id = ? AND pc.is_active = 1) as active_channels_count,
|
|
(SELECT COUNT(*) FROM routes r
|
|
WHERE r.language_id = ? AND r.is_active = 1) as active_routes_count
|
|
", [$languageId, $languageId, $languageId]);
|
|
}
|
|
|
|
/**
|
|
* Get comprehensive language usage summary
|
|
*/
|
|
public function getLanguageUsageSummary(): array
|
|
{
|
|
$results = DB::select("
|
|
SELECT
|
|
l.id,
|
|
l.short_code,
|
|
l.name,
|
|
l.native_name,
|
|
l.is_active,
|
|
COALESCE(feed_stats.active_feeds, 0) as active_feeds_count,
|
|
COALESCE(channel_stats.active_channels, 0) as active_channels_count,
|
|
COALESCE(route_stats.active_routes, 0) as active_routes_count,
|
|
CASE WHEN COALESCE(feed_stats.active_feeds, 0) > 0
|
|
AND COALESCE(channel_stats.active_channels, 0) > 0
|
|
THEN 1 ELSE 0 END as can_create_routes
|
|
FROM languages l
|
|
LEFT JOIN (
|
|
SELECT fl.language_id, COUNT(*) as active_feeds
|
|
FROM feed_languages fl
|
|
INNER JOIN feeds f ON f.id = fl.feed_id
|
|
WHERE fl.is_active = 1 AND f.is_active = 1
|
|
GROUP BY fl.language_id
|
|
) feed_stats ON feed_stats.language_id = l.id
|
|
LEFT JOIN (
|
|
SELECT pc.language_id, COUNT(*) as active_channels
|
|
FROM platform_channels pc
|
|
WHERE pc.is_active = 1
|
|
GROUP BY pc.language_id
|
|
) channel_stats ON channel_stats.language_id = l.id
|
|
LEFT JOIN (
|
|
SELECT r.language_id, COUNT(*) as active_routes
|
|
FROM routes r
|
|
WHERE r.is_active = 1
|
|
GROUP BY r.language_id
|
|
) route_stats ON route_stats.language_id = l.id
|
|
ORDER BY l.name
|
|
");
|
|
|
|
return array_map(fn($row) => (array)$row, $results);
|
|
}
|
|
|
|
/**
|
|
* Find common languages between feed and channel with optimized query
|
|
*/
|
|
public function findCommonLanguages(int $feedId, int $channelId): array
|
|
{
|
|
$results = DB::select("
|
|
SELECT DISTINCT l.id, l.short_code, l.name, l.native_name
|
|
FROM languages l
|
|
INNER JOIN feed_languages fl ON fl.language_id = l.id
|
|
INNER JOIN feeds f ON f.id = fl.feed_id
|
|
INNER JOIN platform_channels pc ON pc.language_id = l.id
|
|
WHERE f.id = ?
|
|
AND pc.id = ?
|
|
AND l.is_active = 1
|
|
AND f.is_active = 1
|
|
AND fl.is_active = 1
|
|
AND pc.is_active = 1
|
|
ORDER BY l.name
|
|
", [$feedId, $channelId]);
|
|
|
|
return array_map(fn($row) => (array)$row, $results);
|
|
}
|
|
|
|
/**
|
|
* Check if language can be used for routes with optimized query
|
|
*/
|
|
public function canLanguageBeUsedForRoutes(int $languageId): bool
|
|
{
|
|
$result = DB::selectOne("
|
|
SELECT
|
|
EXISTS(SELECT 1 FROM feed_languages fl
|
|
JOIN feeds f ON f.id = fl.feed_id
|
|
WHERE fl.language_id = ? AND fl.is_active = 1 AND f.is_active = 1) as has_feeds,
|
|
EXISTS(SELECT 1 FROM platform_channels pc
|
|
WHERE pc.language_id = ? AND pc.is_active = 1) as has_channels
|
|
", [$languageId, $languageId]);
|
|
|
|
return $result->has_feeds && $result->has_channels;
|
|
}
|
|
|
|
/**
|
|
* Get active languages with optional counts
|
|
*/
|
|
public function findActiveLanguages(
|
|
bool $withCounts = false,
|
|
array $select = ['*']
|
|
): Collection {
|
|
$query = $this->model->where('is_active', true);
|
|
|
|
if ($withCounts) {
|
|
$query->withCounts();
|
|
}
|
|
|
|
if ($select !== ['*'] && !empty($select)) {
|
|
$query->select($select);
|
|
}
|
|
|
|
return $query->orderBy('name')->get();
|
|
}
|
|
|
|
/**
|
|
* Batch check language availability for multiple language IDs
|
|
*/
|
|
public function batchCheckLanguageAvailability(array $languageIds): array
|
|
{
|
|
if (empty($languageIds)) {
|
|
return [];
|
|
}
|
|
|
|
$placeholders = str_repeat('?,', count($languageIds) - 1) . '?';
|
|
|
|
$results = DB::select("
|
|
SELECT
|
|
l.id,
|
|
EXISTS(SELECT 1 FROM feed_languages fl
|
|
JOIN feeds f ON f.id = fl.feed_id
|
|
WHERE fl.language_id = l.id AND fl.is_active = 1 AND f.is_active = 1) as has_feeds,
|
|
EXISTS(SELECT 1 FROM platform_channels pc
|
|
WHERE pc.language_id = l.id AND pc.is_active = 1) as has_channels
|
|
FROM languages l
|
|
WHERE l.id IN ({$placeholders}) AND l.is_active = 1
|
|
", $languageIds);
|
|
|
|
$availability = [];
|
|
foreach ($results as $result) {
|
|
$availability[$result->id] = $result->has_feeds && $result->has_channels;
|
|
}
|
|
|
|
return $availability;
|
|
}
|
|
|
|
/**
|
|
* Get language with relationship counts for specific language
|
|
*/
|
|
public function findWithCounts(int $languageId): ?Language
|
|
{
|
|
return $this->model
|
|
->withCounts()
|
|
->find($languageId);
|
|
}
|
|
|
|
/**
|
|
* Search languages by name or code
|
|
*/
|
|
public function search(
|
|
string $term,
|
|
bool $activeOnly = true,
|
|
array $select = ['*']
|
|
): Collection {
|
|
$query = $this->model->select($select)
|
|
->where(function ($q) use ($term) {
|
|
$q->where('name', 'like', "%{$term}%")
|
|
->orWhere('native_name', 'like', "%{$term}%")
|
|
->orWhere('short_code', 'like', "%{$term}%");
|
|
});
|
|
|
|
if ($activeOnly) {
|
|
$query->where('is_active', true);
|
|
}
|
|
|
|
return $query->orderBy('name')->get();
|
|
}
|
|
} |