mirror of
https://code.castopod.org/adaures/castopod
synced 2025-04-19 13:01:19 +00:00
refactor(platforms): move platforms data in code instead of database
refs #457
This commit is contained in:
parent
57e459e187
commit
303a900f66
@ -55,6 +55,7 @@ class Autoload extends AutoloadConfig
|
||||
'Modules\Install' => ROOTPATH . 'modules/Install/',
|
||||
'Modules\Media' => ROOTPATH . 'modules/Media/',
|
||||
'Modules\MediaClipper' => ROOTPATH . 'modules/MediaClipper/',
|
||||
'Modules\Platforms' => ROOTPATH . 'modules/Platforms/',
|
||||
'Modules\PodcastImport' => ROOTPATH . 'modules/PodcastImport/',
|
||||
'Modules\PremiumPodcasts' => ROOTPATH . 'modules/PremiumPodcasts/',
|
||||
'Modules\Update' => ROOTPATH . 'modules/Update/',
|
||||
|
@ -15,7 +15,6 @@ use CodeIgniter\Router\RouteCollection;
|
||||
$routes->addPlaceholder('podcastHandle', '[a-zA-Z0-9\_]{1,32}');
|
||||
$routes->addPlaceholder('slug', '[a-zA-Z0-9\-]{1,128}');
|
||||
$routes->addPlaceholder('base64', '[A-Za-z0-9\.\_]+\-{0,2}');
|
||||
$routes->addPlaceholder('platformType', '\bpodcasting|\bsocial|\bfunding');
|
||||
$routes->addPlaceholder('postAction', '\bfavourite|\breblog|\breply');
|
||||
$routes->addPlaceholder('embedTheme', '\blight|\bdark|\blight-transparent|\bdark-transparent');
|
||||
$routes->addPlaceholder(
|
||||
|
@ -28,6 +28,7 @@ class Routing extends BaseRouting
|
||||
ROOTPATH . 'modules/Auth/Config/Routes.php',
|
||||
ROOTPATH . 'modules/Fediverse/Config/Routes.php',
|
||||
ROOTPATH . 'modules/Install/Config/Routes.php',
|
||||
ROOTPATH . 'modules/Platforms/Config/Routes.php',
|
||||
ROOTPATH . 'modules/PodcastImport/Config/Routes.php',
|
||||
ROOTPATH . 'modules/PremiumPodcasts/Config/Routes.php',
|
||||
];
|
||||
|
@ -1,28 +0,0 @@
|
||||
<?php
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
/**
|
||||
* @copyright 2020 Ad Aures
|
||||
* @license https://www.gnu.org/licenses/agpl-3.0.en.html AGPL3
|
||||
* @link https://castopod.org/
|
||||
*/
|
||||
|
||||
namespace App\Controllers;
|
||||
|
||||
use App\Models\PlatformModel;
|
||||
use CodeIgniter\Controller;
|
||||
use CodeIgniter\HTTP\ResponseInterface;
|
||||
|
||||
/*
|
||||
* Provide public access to all platforms so that they can be exported
|
||||
*/
|
||||
class PlatformController extends Controller
|
||||
{
|
||||
public function index(): ResponseInterface
|
||||
{
|
||||
$model = new PlatformModel();
|
||||
|
||||
return $this->response->setJSON($model->getPlatforms());
|
||||
}
|
||||
}
|
152
app/Database/Migrations/2024-04-18-180000_refactor_platforms.php
Normal file
152
app/Database/Migrations/2024-04-18-180000_refactor_platforms.php
Normal file
@ -0,0 +1,152 @@
|
||||
<?php
|
||||
|
||||
namespace App\Database\Migrations;
|
||||
|
||||
use CodeIgniter\Database\Migration;
|
||||
|
||||
class RefactorPlatforms extends Migration
|
||||
{
|
||||
public function up(): void
|
||||
{
|
||||
$this->forge->addField([
|
||||
'id' => [
|
||||
'type' => 'INT',
|
||||
'unsigned' => true,
|
||||
'auto_increment' => true,
|
||||
],
|
||||
'podcast_id' => [
|
||||
'type' => 'INT',
|
||||
'unsigned' => true,
|
||||
],
|
||||
'type' => [
|
||||
'type' => 'ENUM',
|
||||
'constraint' => ['podcasting', 'social', 'funding'],
|
||||
'after' => 'podcast_id',
|
||||
],
|
||||
'slug' => [
|
||||
'type' => 'VARCHAR',
|
||||
'constraint' => 32,
|
||||
],
|
||||
'link_url' => [
|
||||
'type' => 'VARCHAR',
|
||||
'constraint' => 512,
|
||||
],
|
||||
'account_id' => [
|
||||
'type' => 'VARCHAR',
|
||||
'constraint' => 128,
|
||||
'null' => true,
|
||||
],
|
||||
'is_visible' => [
|
||||
'type' => 'TINYINT',
|
||||
'constraint' => 1,
|
||||
'default' => 0,
|
||||
],
|
||||
]);
|
||||
|
||||
$this->forge->addPrimaryKey('id');
|
||||
$this->forge->addForeignKey('podcast_id', 'podcasts', 'id', '', 'CASCADE', 'platforms_podcast_id_foreign');
|
||||
$this->forge->addUniqueKey(['podcast_id', 'type', 'slug']);
|
||||
$this->forge->createTable('platforms_temp');
|
||||
|
||||
$platformsData = $this->db->table('podcasts_platforms')
|
||||
->select('podcasts_platforms.*, type')
|
||||
->join('platforms', 'platforms.slug = podcasts_platforms.platform_slug')
|
||||
->get()
|
||||
->getResultArray();
|
||||
|
||||
$data = [];
|
||||
foreach ($platformsData as $platformData) {
|
||||
$data[] = [
|
||||
'podcast_id' => $platformData['podcast_id'],
|
||||
'type' => $platformData['type'],
|
||||
'slug' => $platformData['platform_slug'],
|
||||
'link_url' => $platformData['link_url'],
|
||||
'account_id' => $platformData['account_id'],
|
||||
'is_visible' => $platformData['is_visible'],
|
||||
];
|
||||
}
|
||||
|
||||
if ($data !== []) {
|
||||
$this->db->table('platforms_temp')
|
||||
->insertBatch($data);
|
||||
}
|
||||
|
||||
$this->forge->dropTable('platforms');
|
||||
|
||||
$this->forge->dropTable('podcasts_platforms');
|
||||
|
||||
$this->forge->renameTable('platforms_temp', 'platforms');
|
||||
}
|
||||
|
||||
public function down(): void
|
||||
{
|
||||
// delete platforms
|
||||
$this->forge->dropTable('platforms');
|
||||
|
||||
// recreate platforms and podcasts_platforms tables
|
||||
$this->forge->addField([
|
||||
'slug' => [
|
||||
'type' => 'VARCHAR',
|
||||
'constraint' => 32,
|
||||
],
|
||||
'type' => [
|
||||
'type' => 'ENUM',
|
||||
'constraint' => ['podcasting', 'social', 'funding'],
|
||||
],
|
||||
'label' => [
|
||||
'type' => 'VARCHAR',
|
||||
'constraint' => 32,
|
||||
],
|
||||
'home_url' => [
|
||||
'type' => 'VARCHAR',
|
||||
'constraint' => 255,
|
||||
],
|
||||
'submit_url' => [
|
||||
'type' => 'VARCHAR',
|
||||
'constraint' => 512,
|
||||
'null' => true,
|
||||
],
|
||||
]);
|
||||
$this->forge->addField('`created_at` timestamp NOT NULL DEFAULT CURRENT_TIMESTAMP()');
|
||||
$this->forge->addField(
|
||||
'`updated_at` timestamp NOT NULL DEFAULT CURRENT_TIMESTAMP() ON UPDATE CURRENT_TIMESTAMP()'
|
||||
);
|
||||
$this->forge->addPrimaryKey('slug');
|
||||
$this->forge->createTable('platforms');
|
||||
|
||||
$this->forge->addField([
|
||||
'podcast_id' => [
|
||||
'type' => 'INT',
|
||||
'unsigned' => true,
|
||||
],
|
||||
'platform_slug' => [
|
||||
'type' => 'VARCHAR',
|
||||
'constraint' => 32,
|
||||
],
|
||||
'link_url' => [
|
||||
'type' => 'VARCHAR',
|
||||
'constraint' => 512,
|
||||
],
|
||||
'account_id' => [
|
||||
'type' => 'VARCHAR',
|
||||
'constraint' => 128,
|
||||
'null' => true,
|
||||
],
|
||||
'is_visible' => [
|
||||
'type' => 'TINYINT',
|
||||
'constraint' => 1,
|
||||
'default' => 0,
|
||||
],
|
||||
'is_on_embed' => [
|
||||
'type' => 'TINYINT',
|
||||
'constraint' => 1,
|
||||
'default' => 0,
|
||||
],
|
||||
]);
|
||||
|
||||
$this->forge->addPrimaryKey(['podcast_id', 'platform_slug']);
|
||||
$this->forge->addForeignKey('podcast_id', 'podcasts', 'id', '', 'CASCADE');
|
||||
$this->forge->addForeignKey('platform_slug', 'platforms', 'slug', 'CASCADE');
|
||||
$this->forge->createTable('podcasts_platforms');
|
||||
}
|
||||
}
|
@ -20,6 +20,5 @@ class AppSeeder extends Seeder
|
||||
{
|
||||
$this->call('CategorySeeder');
|
||||
$this->call('LanguageSeeder');
|
||||
$this->call('PlatformSeeder');
|
||||
}
|
||||
}
|
||||
|
@ -20,7 +20,6 @@ class DevSeeder extends Seeder
|
||||
{
|
||||
$this->call('CategorySeeder');
|
||||
$this->call('LanguageSeeder');
|
||||
$this->call('PlatformSeeder');
|
||||
$this->call('DevSuperadminSeeder');
|
||||
}
|
||||
}
|
||||
|
@ -15,7 +15,6 @@ use App\Models\ActorModel;
|
||||
use App\Models\CategoryModel;
|
||||
use App\Models\EpisodeModel;
|
||||
use App\Models\PersonModel;
|
||||
use App\Models\PlatformModel;
|
||||
use CodeIgniter\Entity\Entity;
|
||||
use CodeIgniter\Files\File;
|
||||
use CodeIgniter\HTTP\Files\UploadedFile;
|
||||
@ -32,6 +31,8 @@ use League\CommonMark\MarkdownConverter;
|
||||
use Modules\Auth\Models\UserModel;
|
||||
use Modules\Media\Entities\Image;
|
||||
use Modules\Media\Models\MediaModel;
|
||||
use Modules\Platforms\Entities\Platform;
|
||||
use Modules\Platforms\Models\PlatformModel;
|
||||
use Modules\PremiumPodcasts\Entities\Subscription;
|
||||
use Modules\PremiumPodcasts\Models\SubscriptionModel;
|
||||
use RuntimeException;
|
||||
@ -528,7 +529,7 @@ class Podcast extends Entity
|
||||
}
|
||||
|
||||
if ($this->podcasting_platforms === null) {
|
||||
$this->podcasting_platforms = (new PlatformModel())->getPodcastPlatforms($this->id, 'podcasting');
|
||||
$this->podcasting_platforms = (new PlatformModel())->getPlatforms($this->id, 'podcasting');
|
||||
}
|
||||
|
||||
return $this->podcasting_platforms;
|
||||
@ -546,7 +547,7 @@ class Podcast extends Entity
|
||||
}
|
||||
|
||||
if ($this->social_platforms === null) {
|
||||
$this->social_platforms = (new PlatformModel())->getPodcastPlatforms($this->id, 'social');
|
||||
$this->social_platforms = (new PlatformModel())->getPlatforms($this->id, 'social');
|
||||
}
|
||||
|
||||
return $this->social_platforms;
|
||||
@ -564,7 +565,7 @@ class Podcast extends Entity
|
||||
}
|
||||
|
||||
if ($this->funding_platforms === null) {
|
||||
$this->funding_platforms = (new PlatformModel())->getPodcastPlatforms($this->id, 'funding');
|
||||
$this->funding_platforms = (new PlatformModel())->getPlatforms($this->id, 'funding');
|
||||
}
|
||||
|
||||
return $this->funding_platforms;
|
||||
|
@ -1,205 +0,0 @@
|
||||
<?php
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
/**
|
||||
* Class PlatformModel Model for platforms table in database
|
||||
*
|
||||
* @copyright 2020 Ad Aures
|
||||
* @license https://www.gnu.org/licenses/agpl-3.0.en.html AGPL3
|
||||
* @link https://castopod.org/
|
||||
*/
|
||||
|
||||
namespace App\Models;
|
||||
|
||||
use App\Entities\Platform;
|
||||
use CodeIgniter\Model;
|
||||
use Config\App;
|
||||
|
||||
class PlatformModel extends Model
|
||||
{
|
||||
/**
|
||||
* @var string
|
||||
*/
|
||||
protected $table = 'platforms';
|
||||
|
||||
/**
|
||||
* @var string
|
||||
*/
|
||||
protected $primaryKey = 'slug';
|
||||
|
||||
/**
|
||||
* @var string[]
|
||||
*/
|
||||
protected $allowedFields = ['slug', 'type', 'label', 'home_url', 'submit_url'];
|
||||
|
||||
/**
|
||||
* @var string
|
||||
*/
|
||||
protected $returnType = Platform::class;
|
||||
|
||||
/**
|
||||
* @var bool
|
||||
*/
|
||||
protected $useSoftDeletes = false;
|
||||
|
||||
/**
|
||||
* @var bool
|
||||
*/
|
||||
protected $useTimestamps = false;
|
||||
|
||||
/**
|
||||
* @return Platform[]
|
||||
*/
|
||||
public function getPlatforms(): array
|
||||
{
|
||||
if (! ($found = cache('platforms'))) {
|
||||
$baseUrl = rtrim(config(App::class)->baseURL, '/');
|
||||
$found = $this->select(
|
||||
"*, CONCAT('{$baseUrl}/assets/images/platforms/',`type`,'/',`slug`,'.svg') as icon",
|
||||
)->findAll();
|
||||
cache()
|
||||
->save('platforms', $found, DECADE);
|
||||
}
|
||||
|
||||
return $found;
|
||||
}
|
||||
|
||||
public function getPlatform(string $slug): ?Platform
|
||||
{
|
||||
$cacheName = "platform-{$slug}";
|
||||
if (! ($found = cache($cacheName))) {
|
||||
$found = $this->where('slug', $slug)
|
||||
->first();
|
||||
cache()
|
||||
->save($cacheName, $found, DECADE);
|
||||
}
|
||||
|
||||
return $found;
|
||||
}
|
||||
|
||||
public function createPlatform(
|
||||
string $slug,
|
||||
string $type,
|
||||
string $label,
|
||||
string $homeUrl,
|
||||
string $submitUrl = null
|
||||
): bool {
|
||||
$data = [
|
||||
'slug' => $slug,
|
||||
'type' => $type,
|
||||
'label' => $label,
|
||||
'home_url' => $homeUrl,
|
||||
'submit_url' => $submitUrl,
|
||||
];
|
||||
|
||||
return $this->insert($data, false);
|
||||
}
|
||||
|
||||
/**
|
||||
* @return Platform[]
|
||||
*/
|
||||
public function getPlatformsWithLinks(int $podcastId, string $platformType): array
|
||||
{
|
||||
if (
|
||||
! ($found = cache("podcast#{$podcastId}_platforms_{$platformType}_withLinks"))
|
||||
) {
|
||||
$found = $this->select(
|
||||
'platforms.*, podcasts_platforms.link_url, podcasts_platforms.account_id, podcasts_platforms.is_visible, podcasts_platforms.is_on_embed',
|
||||
)
|
||||
->join(
|
||||
'podcasts_platforms',
|
||||
"podcasts_platforms.platform_slug = platforms.slug AND podcasts_platforms.podcast_id = {$podcastId}",
|
||||
'left',
|
||||
)
|
||||
->where('platforms.type', $platformType)
|
||||
->findAll();
|
||||
|
||||
cache()
|
||||
->save("podcast#{$podcastId}_platforms_{$platformType}_withLinks", $found, DECADE);
|
||||
}
|
||||
|
||||
return $found;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return Platform[]
|
||||
*/
|
||||
public function getPodcastPlatforms(int $podcastId, string $platformType): array
|
||||
{
|
||||
$cacheName = "podcast#{$podcastId}_platforms_{$platformType}";
|
||||
if (! ($found = cache($cacheName))) {
|
||||
$found = $this->select(
|
||||
'platforms.*, podcasts_platforms.link_url, podcasts_platforms.account_id, podcasts_platforms.is_visible, podcasts_platforms.is_on_embed',
|
||||
)
|
||||
->join('podcasts_platforms', 'podcasts_platforms.platform_slug = platforms.slug')
|
||||
->where('podcasts_platforms.podcast_id', $podcastId)
|
||||
->where('platforms.type', $platformType)
|
||||
->findAll();
|
||||
|
||||
cache()
|
||||
->save($cacheName, $found, DECADE);
|
||||
}
|
||||
|
||||
return $found;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param mixed[] $podcastsPlatformsData
|
||||
*
|
||||
* @return int|false Number of rows inserted or FALSE on failure
|
||||
*/
|
||||
public function savePodcastPlatforms(
|
||||
int $podcastId,
|
||||
string $platformType,
|
||||
array $podcastsPlatformsData
|
||||
): int | false {
|
||||
$this->clearCache($podcastId);
|
||||
|
||||
$podcastsPlatformsTable = $this->db->prefixTable('podcasts_platforms');
|
||||
$platformsTable = $this->db->prefixTable('platforms');
|
||||
|
||||
$deleteJoinQuery = <<<SQL
|
||||
DELETE {$podcastsPlatformsTable}
|
||||
FROM {$podcastsPlatformsTable}
|
||||
INNER JOIN {$platformsTable} ON {$platformsTable}.slug = {$podcastsPlatformsTable}.platform_slug
|
||||
WHERE `podcast_id` = ? AND `type` = ?
|
||||
SQL;
|
||||
|
||||
$this->db->query($deleteJoinQuery, [$podcastId, $platformType]);
|
||||
|
||||
if ($podcastsPlatformsData === []) {
|
||||
// no rows inserted
|
||||
return 0;
|
||||
}
|
||||
|
||||
return $this->db
|
||||
->table('podcasts_platforms')
|
||||
->insertBatch($podcastsPlatformsData);
|
||||
}
|
||||
|
||||
public function removePodcastPlatform(int $podcastId, string $platformSlug): bool | string
|
||||
{
|
||||
$this->clearCache($podcastId);
|
||||
|
||||
return $this->db->table('podcasts_platforms')
|
||||
->delete([
|
||||
'podcast_id' => $podcastId,
|
||||
'platform_slug' => $platformSlug,
|
||||
]);
|
||||
}
|
||||
|
||||
public function clearCache(int $podcastId): void
|
||||
{
|
||||
cache()->deleteMatching("podcast#{$podcastId}_platforms_*");
|
||||
|
||||
// delete localized podcast page cache
|
||||
cache()
|
||||
->deleteMatching("page_podcast#{$podcastId}*");
|
||||
// delete post and episode comments pages cache
|
||||
cache()
|
||||
->deleteMatching('page_post*');
|
||||
cache()
|
||||
->deleteMatching('page_episode#*');
|
||||
}
|
||||
}
|
@ -1,4 +0,0 @@
|
||||
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24">
|
||||
<path d="M0,0H24V24H0Z" fill="none" />
|
||||
<path d="M13.3,13.07a1.91,1.91,0,0,1,.48,0,2.51,2.51,0,0,1,1.88,1.63c.08.26.19.66.26.93l.09.37h.38a5.49,5.49,0,0,0,5.38-5.46c0-4.52-3.77-8.28-9.54-8.28A10.16,10.16,0,0,0,5.9,4.56,10,10,0,0,0,2.23,12.3a10.64,10.64,0,0,0,.28,2.35,10,10,0,0,0,9.72,7.65,11.07,11.07,0,0,0,1.3-.08A10,10,0,0,0,20,18.6l.1-.12-.2-.73-.38.1a14.32,14.32,0,0,1-3.72.48,14.14,14.14,0,0,1-3-.31,2.51,2.51,0,0,1-1.87-1.65,2.51,2.51,0,0,1,.48-2.44A2.5,2.5,0,0,1,13.3,13.07ZM12.23,3.24c5.34,0,8.6,3.42,8.6,7.34a4.55,4.55,0,0,1-4.1,4.5c-.06-.22-.13-.45-.18-.62a15.25,15.25,0,0,0-9.36-9.7A8.79,8.79,0,0,1,12.23,3.24ZM3.17,12.3A9,9,0,0,1,6.3,5.45a14.35,14.35,0,0,1,8.38,7A3.26,3.26,0,0,0,14,12.2a15.86,15.86,0,0,0-3.17-.33,15.65,15.65,0,0,0-7.51,1.94A9.33,9.33,0,0,1,3.17,12.3Zm9.44,6.64a15.9,15.9,0,0,0,3.19.33,16.77,16.77,0,0,0,2.46-.19,9,9,0,0,1-4.6,2.17,13.91,13.91,0,0,1-1.73-2.52A3.83,3.83,0,0,0,12.61,18.94Zm-.07,2.42h-.31a8.82,8.82,0,0,1-4.16-1A14.24,14.24,0,0,1,9.88,16a4.07,4.07,0,0,0,.16.71A15.68,15.68,0,0,0,12.54,21.36Zm-1.83-8a15.6,15.6,0,0,0-3.48,6.55,9,9,0,0,1-3.72-5.1,14.27,14.27,0,0,1,7.29-1.95h.44A3.57,3.57,0,0,0,10.71,13.31Z" />
|
||||
</svg>
|
Before Width: | Height: | Size: 1.2 KiB |
@ -1,4 +0,0 @@
|
||||
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24">
|
||||
<path d="M0,0H24V24H0Z" fill="none" />
|
||||
<path d="M3.22,10.08A1.24,1.24,0,0,0,2,11.31V12.7a1.22,1.22,0,0,0,2.44,0h0V11.31A1.17,1.17,0,0,0,3.22,10.08Zm17.56,0a1.23,1.23,0,0,0-1.22,1.23V12.7a1.21,1.21,0,0,0,1.22,1.22A1.22,1.22,0,0,0,22,12.7h0V11.31A1.24,1.24,0,0,0,20.78,10.08ZM7.56,14.2a1.24,1.24,0,0,0-1.23,1.23v1.4a1.23,1.23,0,0,0,2.45,0h0v-1.4A1.17,1.17,0,0,0,7.56,14.2ZM7.56,6A1.24,1.24,0,0,0,6.33,7.24V11.7h0a1.23,1.23,0,0,0,2.45,0h0V7.24A1.17,1.17,0,0,0,7.56,6Zm8.88,0a1.24,1.24,0,0,0-1.22,1.23V8.63a1.23,1.23,0,0,0,2.45,0h0V7.24A1.24,1.24,0,0,0,16.44,6ZM12,2a1.23,1.23,0,0,0-1.22,1.23V4.62a1.22,1.22,0,1,0,2.44,0h0V3.23A1.23,1.23,0,0,0,12,2Zm0,16.16a1.22,1.22,0,0,0-1.22,1.22v1.4a1.22,1.22,0,1,0,2.44,0h0v-1.4A1.26,1.26,0,0,0,12,18.16Zm4.44-7a1.23,1.23,0,0,0-1.22,1.22v4.47a1.23,1.23,0,0,0,2.45,0h0V12.36A1.23,1.23,0,0,0,16.44,11.14ZM13.22,8.41a1.22,1.22,0,0,0-2.44,0h0v7.36h0a1.22,1.22,0,1,0,2.44,0h0V8.41Z" />
|
||||
</svg>
|
Before Width: | Height: | Size: 991 B |
@ -28,17 +28,18 @@ class Button extends Component
|
||||
public function render(): string
|
||||
{
|
||||
$baseClass =
|
||||
'gap-x-2 flex-shrink-0 inline-flex items-center justify-center font-semibold shadow-xs rounded-full focus:ring-accent';
|
||||
'gap-x-2 flex-shrink-0 inline-flex items-center justify-center font-semibold rounded-full focus:ring-accent';
|
||||
|
||||
$variantClass = [
|
||||
'default' => 'text-black bg-gray-300 hover:bg-gray-400',
|
||||
'primary' => 'text-accent-contrast bg-accent-base hover:bg-accent-hover',
|
||||
'secondary' => 'border-2 border-accent-base text-accent-base bg-white hover:border-accent-hover hover:text-accent-hover',
|
||||
'success' => 'text-white bg-pine-500 hover:bg-pine-800',
|
||||
'danger' => 'text-white bg-red-600 hover:bg-red-700',
|
||||
'warning' => 'text-black bg-yellow-500 hover:bg-yellow-600',
|
||||
'info' => 'text-white bg-blue-500 hover:bg-blue-600',
|
||||
'disabled' => 'text-black bg-gray-300 cursor-not-allowed',
|
||||
'default' => 'shadow-sm text-black bg-gray-300 hover:bg-gray-400',
|
||||
'primary' => 'shadow-sm text-accent-contrast bg-accent-base hover:bg-accent-hover',
|
||||
'secondary' => 'shadow-sm border-2 border-accent-base text-accent-base bg-white hover:border-accent-hover hover:text-accent-hover',
|
||||
'success' => 'shadow-sm text-white bg-pine-500 hover:bg-pine-800',
|
||||
'danger' => 'shadow-sm text-white bg-red-600 hover:bg-red-700',
|
||||
'warning' => 'shadow-sm text-black bg-yellow-500 hover:bg-yellow-600',
|
||||
'info' => 'shadow-sm text-white bg-blue-500 hover:bg-blue-600',
|
||||
'disabled' => 'shadow-sm text-black bg-gray-300 cursor-not-allowed',
|
||||
'link' => 'text-accent-base bg-transparent underline hover:no-underline',
|
||||
];
|
||||
|
||||
$sizeClass = [
|
||||
|
@ -303,11 +303,8 @@ You may skip this section if you go through the install wizard (go to
|
||||
# Populates all Languages
|
||||
php spark db:seed LanguageSeeder
|
||||
|
||||
# Populates all podcasts platforms
|
||||
php spark db:seed PlatformSeeder
|
||||
|
||||
# Adds a superadmin with [admin@castopod.local / castopod] credentials
|
||||
php spark db:seed PlatformSeeder
|
||||
php spark db:seed DevSuperadminSeeder
|
||||
```
|
||||
|
||||
3. (optionnal) Populate the database with test data:
|
||||
|
@ -511,48 +511,6 @@ $routes->group(
|
||||
});
|
||||
});
|
||||
});
|
||||
$routes->group('platforms', static function ($routes): void {
|
||||
$routes->get(
|
||||
'/',
|
||||
'PodcastPlatformController::platforms/$1/podcasting',
|
||||
[
|
||||
'as' => 'platforms-podcasting',
|
||||
'filter' => 'permission:podcast#.manage-platforms',
|
||||
],
|
||||
);
|
||||
$routes->get(
|
||||
'social',
|
||||
'PodcastPlatformController::platforms/$1/social',
|
||||
[
|
||||
'as' => 'platforms-social',
|
||||
'filter' => 'permission:podcast#.manage-platforms',
|
||||
],
|
||||
);
|
||||
$routes->get(
|
||||
'funding',
|
||||
'PodcastPlatformController::platforms/$1/funding',
|
||||
[
|
||||
'as' => 'platforms-funding',
|
||||
'filter' => 'permission:podcast#.manage-platforms',
|
||||
],
|
||||
);
|
||||
$routes->post(
|
||||
'save/(:platformType)',
|
||||
'PodcastPlatformController::attemptPlatformsUpdate/$1/$2',
|
||||
[
|
||||
'as' => 'platforms-save',
|
||||
'filter' => 'permission:podcast#.manage-platforms',
|
||||
],
|
||||
);
|
||||
$routes->get(
|
||||
'(:slug)/podcast-platform-remove',
|
||||
'PodcastPlatformController::removePodcastPlatform/$1/$2',
|
||||
[
|
||||
'as' => 'podcast-platform-remove',
|
||||
'filter' => 'permission:podcast#.manage-platforms',
|
||||
],
|
||||
);
|
||||
});
|
||||
// Podcast notifications
|
||||
$routes->group('notifications', static function ($routes): void {
|
||||
$routes->get('/', 'NotificationController::list/$1', [
|
||||
|
65
modules/Platforms/Config/Routes.php
Normal file
65
modules/Platforms/Config/Routes.php
Normal file
@ -0,0 +1,65 @@
|
||||
<?php
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
namespace Modules\PremiumPodcasts\Config;
|
||||
|
||||
use CodeIgniter\Router\RouteCollection;
|
||||
use Modules\Admin\Config\Admin;
|
||||
|
||||
$routes->addPlaceholder('platformType', '\bpodcasting|\bsocial|\bfunding');
|
||||
|
||||
/** @var RouteCollection $routes */
|
||||
|
||||
// Admin routes for subscriptions
|
||||
$routes->group(
|
||||
config(Admin::class)
|
||||
->gateway,
|
||||
[
|
||||
'namespace' => 'Modules\Platforms\Controllers',
|
||||
],
|
||||
static function ($routes): void {
|
||||
$routes->group('podcasts/(:num)/platforms', static function ($routes): void {
|
||||
$routes->get(
|
||||
'/',
|
||||
'PlatformController::platforms/$1/podcasting',
|
||||
[
|
||||
'as' => 'platforms-podcasting',
|
||||
'filter' => 'permission:podcast#.manage-platforms',
|
||||
],
|
||||
);
|
||||
$routes->get(
|
||||
'social',
|
||||
'PlatformController::platforms/$1/social',
|
||||
[
|
||||
'as' => 'platforms-social',
|
||||
'filter' => 'permission:podcast#.manage-platforms',
|
||||
],
|
||||
);
|
||||
$routes->get(
|
||||
'funding',
|
||||
'PlatformController::platforms/$1/funding',
|
||||
[
|
||||
'as' => 'platforms-funding',
|
||||
'filter' => 'permission:podcast#.manage-platforms',
|
||||
],
|
||||
);
|
||||
$routes->post(
|
||||
'save/(:platformType)',
|
||||
'PlatformController::attemptPlatformsUpdate/$1/$2',
|
||||
[
|
||||
'as' => 'platforms-save',
|
||||
'filter' => 'permission:podcast#.manage-platforms',
|
||||
],
|
||||
);
|
||||
$routes->get(
|
||||
'(:platformType)/(:slug)/podcast-platform-remove',
|
||||
'PlatformController::removePlatform/$1/$2/$3',
|
||||
[
|
||||
'as' => 'podcast-platform-remove',
|
||||
'filter' => 'permission:podcast#.manage-platforms',
|
||||
],
|
||||
);
|
||||
});
|
||||
}
|
||||
);
|
@ -8,18 +8,19 @@ declare(strict_types=1);
|
||||
* @link https://castopod.org/
|
||||
*/
|
||||
|
||||
namespace Modules\Admin\Controllers;
|
||||
namespace Modules\Platforms\Controllers;
|
||||
|
||||
use App\Entities\Podcast;
|
||||
use App\Models\PlatformModel;
|
||||
use App\Models\PodcastModel;
|
||||
use CodeIgniter\Exceptions\PageNotFoundException;
|
||||
use CodeIgniter\HTTP\RedirectResponse;
|
||||
use Config\Services;
|
||||
use Modules\Admin\Controllers\BaseController;
|
||||
use Modules\Platforms\Models\PlatformModel;
|
||||
|
||||
class PodcastPlatformController extends BaseController
|
||||
class PlatformController extends BaseController
|
||||
{
|
||||
protected ?Podcast $podcast;
|
||||
protected Podcast $podcast;
|
||||
|
||||
public function _remap(string $method, string ...$params): mixed
|
||||
{
|
||||
@ -28,18 +29,20 @@ class PodcastPlatformController extends BaseController
|
||||
}
|
||||
|
||||
if (
|
||||
($this->podcast = (new PodcastModel())->getPodcastById((int) $params[0])) instanceof Podcast
|
||||
! ($podcast = (new PodcastModel())->getPodcastById((int) $params[0])) instanceof Podcast
|
||||
) {
|
||||
unset($params[0]);
|
||||
return $this->{$method}(...$params);
|
||||
throw PageNotFoundException::forPageNotFound();
|
||||
}
|
||||
|
||||
throw PageNotFoundException::forPageNotFound();
|
||||
$this->podcast = $podcast;
|
||||
|
||||
unset($params[0]);
|
||||
return $this->{$method}(...$params);
|
||||
}
|
||||
|
||||
public function index(): string
|
||||
{
|
||||
return view('podcast/platforms\dashboard');
|
||||
return view('podcast/platforms/dashboard');
|
||||
}
|
||||
|
||||
public function platforms(string $platformType): string
|
||||
@ -49,7 +52,7 @@ class PodcastPlatformController extends BaseController
|
||||
$data = [
|
||||
'podcast' => $this->podcast,
|
||||
'platformType' => $platformType,
|
||||
'platforms' => (new PlatformModel())->getPlatformsWithLinks($this->podcast->id, $platformType),
|
||||
'platforms' => (new PlatformModel())->getPlatformsWithData($this->podcast->id, $platformType),
|
||||
];
|
||||
|
||||
replace_breadcrumb_params([
|
||||
@ -64,8 +67,7 @@ class PodcastPlatformController extends BaseController
|
||||
$platformModel = new PlatformModel();
|
||||
$validation = Services::validation();
|
||||
|
||||
$podcastsPlatformsData = [];
|
||||
|
||||
$platformsData = [];
|
||||
foreach (
|
||||
$this->request->getPost('platforms')
|
||||
as $platformSlug => $podcastPlatform
|
||||
@ -80,30 +82,27 @@ class PodcastPlatformController extends BaseController
|
||||
}
|
||||
|
||||
$podcastPlatformAccountId = trim((string) $podcastPlatform['account_id']);
|
||||
$podcastsPlatformsData[] = [
|
||||
'platform_slug' => $platformSlug,
|
||||
'podcast_id' => $this->podcast->id,
|
||||
'link_url' => $podcastPlatformUrl,
|
||||
'account_id' => $podcastPlatformAccountId === '' ? null : $podcastPlatformAccountId,
|
||||
'is_visible' => array_key_exists('visible', $podcastPlatform) &&
|
||||
$platformsData[] = [
|
||||
'podcast_id' => $this->podcast->id,
|
||||
'type' => $platformType,
|
||||
'slug' => $platformSlug,
|
||||
'link_url' => $podcastPlatformUrl,
|
||||
'account_id' => $podcastPlatformAccountId === '' ? null : $podcastPlatformAccountId,
|
||||
'is_visible' => array_key_exists('visible', $podcastPlatform) &&
|
||||
$podcastPlatform['visible'] === 'yes',
|
||||
'is_on_embed' => array_key_exists(
|
||||
'on_embed',
|
||||
$podcastPlatform
|
||||
) && $podcastPlatform['on_embed'] === 'yes',
|
||||
];
|
||||
}
|
||||
|
||||
$platformModel->savePodcastPlatforms($this->podcast->id, $platformType, $podcastsPlatformsData);
|
||||
$platformModel->savePlatforms($this->podcast->id, $platformType, $platformsData);
|
||||
|
||||
return redirect()
|
||||
->back()
|
||||
->with('message', lang('Platforms.messages.updateSuccess'));
|
||||
}
|
||||
|
||||
public function removePodcastPlatform(string $platformSlug): RedirectResponse
|
||||
public function removePlatform(string $platformType, string $platformSlug): RedirectResponse
|
||||
{
|
||||
(new PlatformModel())->removePodcastPlatform($this->podcast->id, $platformSlug);
|
||||
(new PlatformModel())->removePlatform($this->podcast->id, $platformType, $platformSlug);
|
||||
|
||||
return redirect()
|
||||
->back()
|
@ -8,20 +8,20 @@ declare(strict_types=1);
|
||||
* @link https://castopod.org/
|
||||
*/
|
||||
|
||||
namespace App\Entities;
|
||||
namespace Modules\Platforms\Entities;
|
||||
|
||||
use CodeIgniter\Entity\Entity;
|
||||
|
||||
/**
|
||||
* @property int $podcast_id
|
||||
* @property string $slug
|
||||
* @property string $type
|
||||
* @property string $label
|
||||
* @property string $link_url
|
||||
* @property string|null $account_id
|
||||
* @property bool $is_visible
|
||||
* @property string $home_url
|
||||
* @property string|null $submit_url
|
||||
* @property string|null $link_url
|
||||
* @property string|null $account_id
|
||||
* @property bool|null $is_visible
|
||||
* @property bool|null $is_on_embed
|
||||
*/
|
||||
class Platform extends Entity
|
||||
{
|
||||
@ -29,14 +29,14 @@ class Platform extends Entity
|
||||
* @var array<string, string>
|
||||
*/
|
||||
protected $casts = [
|
||||
'slug' => 'string',
|
||||
'type' => 'string',
|
||||
'label' => 'string',
|
||||
'home_url' => 'string',
|
||||
'submit_url' => '?string',
|
||||
'link_url' => '?string',
|
||||
'account_id' => '?string',
|
||||
'is_visible' => '?boolean',
|
||||
'is_on_embed' => '?boolean',
|
||||
'podcast_id' => 'int',
|
||||
'slug' => 'string',
|
||||
'type' => 'string',
|
||||
'label' => 'string',
|
||||
'link_url' => 'string',
|
||||
'account_id' => '?string',
|
||||
'is_visible' => 'boolean',
|
||||
'home_url' => 'string',
|
||||
'submit_url' => '?string',
|
||||
];
|
||||
}
|
178
modules/Platforms/Models/PlatformModel.php
Normal file
178
modules/Platforms/Models/PlatformModel.php
Normal file
@ -0,0 +1,178 @@
|
||||
<?php
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
/**
|
||||
* Class PlatformModel Model for platforms table in database
|
||||
*
|
||||
* @copyright 2024 Ad Aures
|
||||
* @license https://www.gnu.org/licenses/agpl-3.0.en.html AGPL3
|
||||
* @link https://castopod.org/
|
||||
*/
|
||||
|
||||
namespace Modules\Platforms\Models;
|
||||
|
||||
use CodeIgniter\Model;
|
||||
use Modules\Platforms\Entities\Platform;
|
||||
use Modules\Platforms\Platforms;
|
||||
|
||||
class PlatformModel extends Model
|
||||
{
|
||||
/**
|
||||
* @var string
|
||||
*/
|
||||
protected $table = 'platforms';
|
||||
|
||||
/**
|
||||
* @var string
|
||||
*/
|
||||
protected $primaryKey = 'id';
|
||||
|
||||
/**
|
||||
* @var string[]
|
||||
*/
|
||||
protected $allowedFields = ['podcast_id', 'type', 'slug', 'link_url', 'account_id', 'is_visible'];
|
||||
|
||||
/**
|
||||
* @var string
|
||||
*/
|
||||
protected $returnType = Platform::class;
|
||||
|
||||
/**
|
||||
* @var bool
|
||||
*/
|
||||
protected $useSoftDeletes = false;
|
||||
|
||||
/**
|
||||
* @var bool
|
||||
*/
|
||||
protected $useTimestamps = false;
|
||||
|
||||
/**
|
||||
* @return Platform[]
|
||||
*/
|
||||
public function getPlatformsWithData(int $podcastId, string $platformType): array
|
||||
{
|
||||
$cacheName = "podcast#{$podcastId}_platforms_{$platformType}_withData";
|
||||
if (! ($found = cache($cacheName))) {
|
||||
$platforms = new Platforms();
|
||||
|
||||
$found = $this->getPlatforms($podcastId, $platformType);
|
||||
$platformsData = $platforms->getPlatformsByType($platformType);
|
||||
|
||||
$knownSlugs = [];
|
||||
foreach ($found as $podcastPlatform) {
|
||||
$knownSlugs[] = $podcastPlatform->slug;
|
||||
}
|
||||
|
||||
foreach ($platformsData as $slug => $platform) {
|
||||
if (! in_array($slug, $knownSlugs)) {
|
||||
$found[] = new Platform([
|
||||
'podcast_id' => $podcastId,
|
||||
'slug' => $slug,
|
||||
'type' => $platformType,
|
||||
'label' => $platform['label'],
|
||||
'home_url' => $platform['home_url'],
|
||||
'submit_url' => $platform['submit_url'],
|
||||
'link_url' => '',
|
||||
'account_id' => null,
|
||||
'is_visible' => false,
|
||||
]);
|
||||
}
|
||||
}
|
||||
|
||||
cache()
|
||||
->save($cacheName, $found, DECADE);
|
||||
}
|
||||
|
||||
return $found;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return Platform[]
|
||||
*/
|
||||
public function getPlatforms(int $podcastId, string $platformType): array
|
||||
{
|
||||
$cacheName = "podcast#{$podcastId}_platforms_{$platformType}";
|
||||
if (! ($found = cache($cacheName))) {
|
||||
$platforms = new Platforms();
|
||||
|
||||
/** @var Platform[] $found */
|
||||
$found = $this
|
||||
->where('podcast_id', $podcastId)
|
||||
->where('type', $platformType)
|
||||
->orderBy('slug')
|
||||
->findAll();
|
||||
|
||||
foreach ($found as $platform) {
|
||||
$platformData = $platforms->findPlatformBySlug($platformType, $platform->slug);
|
||||
|
||||
if ($platformData === null) {
|
||||
// delete platform, it does not correspond to any existing one
|
||||
$this->delete($platform->id);
|
||||
|
||||
continue;
|
||||
}
|
||||
|
||||
$platform->type = $platformType;
|
||||
$platform->label = $platformData['label'];
|
||||
$platform->home_url = $platformData['home_url'];
|
||||
$platform->submit_url = $platformData['submit_url'];
|
||||
}
|
||||
|
||||
cache()
|
||||
->save($cacheName, $found, DECADE);
|
||||
}
|
||||
|
||||
return $found;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return int|false Number of rows inserted or FALSE on failure
|
||||
*/
|
||||
public function savePlatforms(int $podcastId, string $platformType, array $data): int | false
|
||||
{
|
||||
$this->clearCache($podcastId);
|
||||
|
||||
$platforms = new Platforms();
|
||||
|
||||
$platformsData = $platforms->getPlatformsByType($platformType);
|
||||
|
||||
$this->builder()
|
||||
->whereIn('slug', array_keys($platformsData))
|
||||
->delete();
|
||||
|
||||
if ($data === []) {
|
||||
// no rows inserted
|
||||
return 0;
|
||||
}
|
||||
|
||||
return $this->insertBatch($data);
|
||||
}
|
||||
|
||||
public function removePlatform(int $podcastId, string $platformType, string $platformSlug): bool | string
|
||||
{
|
||||
$this->clearCache($podcastId);
|
||||
|
||||
return $this->builder()
|
||||
->delete([
|
||||
'podcast_id' => $podcastId,
|
||||
'type' => $platformType,
|
||||
'slug' => $platformSlug,
|
||||
]);
|
||||
}
|
||||
|
||||
public function clearCache(int $podcastId): void
|
||||
{
|
||||
cache()->deleteMatching("podcast#{$podcastId}_platforms_*");
|
||||
|
||||
// delete localized podcast page cache
|
||||
cache()
|
||||
->deleteMatching("page_podcast#{$podcastId}*");
|
||||
// delete post and episode comments pages cache
|
||||
cache()
|
||||
->deleteMatching('page_post*');
|
||||
cache()
|
||||
->deleteMatching('page_episode#*');
|
||||
}
|
||||
}
|
File diff suppressed because it is too large
Load Diff
@ -8,11 +8,9 @@ use AdAures\PodcastPersonsTaxonomy\ReversedTaxonomy;
|
||||
use App\Entities\Episode;
|
||||
use App\Entities\Location;
|
||||
use App\Entities\Person;
|
||||
use App\Entities\Platform;
|
||||
use App\Entities\Podcast;
|
||||
use App\Models\EpisodeModel;
|
||||
use App\Models\PersonModel;
|
||||
use App\Models\PlatformModel;
|
||||
use App\Models\PodcastModel;
|
||||
use CodeIgniter\CLI\BaseCommand;
|
||||
use CodeIgniter\CLI\CLI;
|
||||
@ -23,6 +21,8 @@ use Exception;
|
||||
use League\HTMLToMarkdown\HtmlConverter;
|
||||
use Modules\Auth\Config\AuthGroups;
|
||||
use Modules\Auth\Models\UserModel;
|
||||
use Modules\Platforms\Models\PlatformModel;
|
||||
use Modules\Platforms\Platforms;
|
||||
use Modules\PodcastImport\Entities\PodcastImportTask;
|
||||
use Modules\PodcastImport\Entities\TaskStatus;
|
||||
use PodcastFeed\PodcastFeed;
|
||||
@ -392,27 +392,32 @@ class PodcastImport extends BaseCommand
|
||||
],
|
||||
];
|
||||
|
||||
$platforms = new Platforms();
|
||||
$platformModel = new PlatformModel();
|
||||
foreach ($platformTypes as $platformType) {
|
||||
$podcastsPlatformsData = [];
|
||||
$platformsData = [];
|
||||
$currPlatformStep = 1; // for progress
|
||||
CLI::write($platformType['name'] . ' - ' . $platformType['count'] . ' elements');
|
||||
foreach ($platformType['elements'] as $platform) {
|
||||
CLI::showProgress($currPlatformStep++, $platformType['count']);
|
||||
$platformLabel = $platform->getAttribute('platform');
|
||||
$platformSlug = slugify((string) $platformLabel);
|
||||
if ($platformModel->getPlatform($platformSlug) instanceof Platform) {
|
||||
$podcastsPlatformsData[] = [
|
||||
'platform_slug' => $platformSlug,
|
||||
'podcast_id' => $this->podcast->id,
|
||||
'link_url' => $platform->getAttribute($platformType['account_url_key']),
|
||||
'account_id' => $platform->getAttribute($platformType['account_id_key']),
|
||||
'is_visible' => false,
|
||||
];
|
||||
$platformSlug = $platform->getAttribute('platform');
|
||||
$platformData = $platforms->findPlatformBySlug($platformType['name'], $platformSlug);
|
||||
|
||||
if ($platformData === null) {
|
||||
continue;
|
||||
}
|
||||
|
||||
$platformsData[] = [
|
||||
'podcast_id' => $this->podcast->id,
|
||||
'type' => $platformType['name'],
|
||||
'slug' => $platformSlug,
|
||||
'link_url' => $platform->getAttribute($platformType['account_url_key']),
|
||||
'account_id' => $platform->getAttribute($platformType['account_id_key']),
|
||||
'is_visible' => false,
|
||||
];
|
||||
}
|
||||
|
||||
$platformModel->savePodcastPlatforms($this->podcast->id, $platformType['name'], $podcastsPlatformsData);
|
||||
$platformModel->savePlatforms($this->podcast->id, $platformType['name'], $platformsData);
|
||||
CLI::showProgress(false);
|
||||
}
|
||||
}
|
||||
|
19514
pnpm-lock.yaml
generated
19514
pnpm-lock.yaml
generated
File diff suppressed because it is too large
Load Diff
@ -117,6 +117,7 @@ module.exports = {
|
||||
cards: "repeat(auto-fill, minmax(14rem, 1fr))",
|
||||
latestEpisodes: "repeat(5, 1fr)",
|
||||
colorButtons: "repeat(auto-fill, minmax(4rem, 1fr))",
|
||||
platforms: "repeat(auto-fill, minmax(18rem, 1fr))",
|
||||
},
|
||||
gridTemplateRows: {
|
||||
admin: "40px 1fr",
|
||||
|
@ -14,9 +14,10 @@
|
||||
|
||||
<?= $this->section('content') ?>
|
||||
|
||||
<form id="platforms-form" action="<?= route_to('platforms-save', $podcast->id, $platformType) ?>" method="POST" class="flex flex-col max-w-md gap-y-8">
|
||||
<form id="platforms-form" action="<?= route_to('platforms-save', $podcast->id, $platformType) ?>" method="POST" class="grid w-full gap-4 lg:gap-8 grid-cols-platforms">
|
||||
<?= csrf_field() ?>
|
||||
|
||||
|
||||
<?php foreach ($platforms as $platform): ?>
|
||||
|
||||
<div class="relative flex-col items-start p-4 rounded-lg bg-elevated border-3 <?= $platform->link_url ? 'border-accent-base' : 'border-subtle' ?>">
|
||||
@ -24,7 +25,8 @@
|
||||
route_to(
|
||||
'podcast-platform-remove',
|
||||
$podcast->id,
|
||||
esc($platform->slug),
|
||||
$platform->type,
|
||||
$platform->slug,
|
||||
),
|
||||
icon('delete-bin', 'mx-auto'),
|
||||
[
|
||||
@ -36,7 +38,7 @@
|
||||
],
|
||||
)
|
||||
: '' ?>
|
||||
<div class="flex items-center gap-x-4">
|
||||
<div class="flex items-center gap-x-2">
|
||||
<?= icon(
|
||||
esc($platform->slug),
|
||||
'text-skin-muted text-4xl',
|
||||
@ -45,29 +47,15 @@
|
||||
<h2 class="text-xl font-semibold"><?= $platform->label ?></h2>
|
||||
</div>
|
||||
<div class="flex flex-col flex-1 mt-4">
|
||||
<div class="inline-flex ml-12 gap-x-2">
|
||||
<?= anchor($platform->home_url, icon('external-link', 'mx-auto') . lang('Platforms.website'), [
|
||||
'class' => 'gap-x-1 flex-shrink-0 inline-flex items-center justify-center font-semibold shadow-xs rounded-full focus:ring-accent px-2 py-1 text-sm border-2 border-accent-base text-accent-base bg-white hover:border-accent-hover hover:text-accent-hover',
|
||||
'target' => '_blank',
|
||||
'rel' => 'noopener noreferrer',
|
||||
'data-tooltip' => 'bottom',
|
||||
'title' => lang('Platforms.home_url', [
|
||||
<div class="inline-flex ml-8 -mt-6 gap-x-1">
|
||||
<Button uri="<?= $platform->home_url ?>" variant="link" size="small" target="_blank" rel="noopener noreferrer" title="<?= lang('Platforms.home_url', [
|
||||
'platformName' => $platform->label,
|
||||
]) ?>" data-tooltip="bottom"><?= lang('Platforms.website') ?></Button>
|
||||
<?php if ($platform->submit_url !== null): ?>
|
||||
<Button uri="<?= $platform->submit_url ?>" variant="link" size="small" target="_blank" rel="noopener noreferrer" title="<?= lang('Platforms.submit_url', [
|
||||
'platformName' => $platform->label,
|
||||
]),
|
||||
]) ?>
|
||||
<?= $platform->submit_url ? anchor(
|
||||
$platform->submit_url,
|
||||
icon('add') . lang('Platforms.register'),
|
||||
[
|
||||
'class' => 'gap-x-1 flex-shrink-0 inline-flex items-center justify-center font-semibold shadow-xs rounded-full focus:ring-accent px-2 py-1 text-sm border-2 border-accent-base text-accent-base bg-white hover:border-accent-hover hover:text-accent-hover',
|
||||
'target' => '_blank',
|
||||
'rel' => 'noopener noreferrer',
|
||||
'data-tooltip' => 'bottom',
|
||||
'title' => lang('Platforms.submit_url', [
|
||||
'platformName' => $platform->label,
|
||||
]),
|
||||
]
|
||||
) : '' ?>
|
||||
]) ?>" data-tooltip="bottom"><?= lang('Platforms.register') ?></Button>
|
||||
<?php endif; ?>
|
||||
</div>
|
||||
<fieldset>
|
||||
<Forms.Field
|
||||
|
Loading…
x
Reference in New Issue
Block a user