Skip to content
Snippets Groups Projects

Compare revisions

Changes are shown as if the source revision was being merged into the target revision. Learn more about comparing revisions.

Source

Select target project
No results found

Target

Select target project
  • adaures/castopod
  • mkljczk/castopod-host
  • spaetz/castopod-host
  • PatrykMis/castopod
  • jonas/castopod
  • ajeremias/castopod
  • misuzu/castopod
  • KrzysztofDomanczyk/castopod
  • Behel/castopod
  • nebulon/castopod
  • ewen/castopod
  • NeoluxConsulting/castopod
  • nateritter/castopod-og
  • prcutler/castopod
14 results
Show changes
Showing
with 512 additions and 23 deletions
...@@ -12,8 +12,11 @@ declare(strict_types=1); ...@@ -12,8 +12,11 @@ declare(strict_types=1);
namespace App\Database\Migrations; namespace App\Database\Migrations;
use Override;
class AddEpisodesPersons extends BaseMigration class AddEpisodesPersons extends BaseMigration
{ {
#[Override]
public function up(): void public function up(): void
{ {
$this->forge->addField([ $this->forge->addField([
...@@ -51,6 +54,7 @@ class AddEpisodesPersons extends BaseMigration ...@@ -51,6 +54,7 @@ class AddEpisodesPersons extends BaseMigration
$this->forge->createTable('episodes_persons'); $this->forge->createTable('episodes_persons');
} }
#[Override]
public function down(): void public function down(): void
{ {
$this->forge->dropTable('episodes_persons'); $this->forge->dropTable('episodes_persons');
......
...@@ -10,8 +10,11 @@ declare(strict_types=1); ...@@ -10,8 +10,11 @@ declare(strict_types=1);
namespace App\Database\Migrations; namespace App\Database\Migrations;
use Override;
class AddCreditsView extends BaseMigration class AddCreditsView extends BaseMigration
{ {
#[Override]
public function up(): void public function up(): void
{ {
// Creates View for credit UNION query // Creates View for credit UNION query
...@@ -37,6 +40,7 @@ class AddCreditsView extends BaseMigration ...@@ -37,6 +40,7 @@ class AddCreditsView extends BaseMigration
$this->db->query($createQuery); $this->db->query($createQuery);
} }
#[Override]
public function down(): void public function down(): void
{ {
$viewName = $this->db->prefixTable('credits'); $viewName = $this->db->prefixTable('credits');
......
...@@ -12,8 +12,11 @@ declare(strict_types=1); ...@@ -12,8 +12,11 @@ declare(strict_types=1);
namespace App\Database\Migrations; namespace App\Database\Migrations;
use Override;
class AddEpisodeIdToPosts extends BaseMigration class AddEpisodeIdToPosts extends BaseMigration
{ {
#[Override]
public function up(): void public function up(): void
{ {
$prefix = $this->db->getPrefix(); $prefix = $this->db->getPrefix();
...@@ -33,11 +36,12 @@ class AddEpisodeIdToPosts extends BaseMigration ...@@ -33,11 +36,12 @@ class AddEpisodeIdToPosts extends BaseMigration
'id', 'id',
'', '',
'CASCADE', 'CASCADE',
$prefix . 'fediverse_posts_episode_id_foreign' $prefix . 'fediverse_posts_episode_id_foreign',
); );
$this->forge->processIndexes('fediverse_posts'); $this->forge->processIndexes('fediverse_posts');
} }
#[Override]
public function down(): void public function down(): void
{ {
$prefix = $this->db->getPrefix(); $prefix = $this->db->getPrefix();
......
...@@ -12,8 +12,11 @@ declare(strict_types=1); ...@@ -12,8 +12,11 @@ declare(strict_types=1);
namespace App\Database\Migrations; namespace App\Database\Migrations;
use Override;
class AddCreatedByToPosts extends BaseMigration class AddCreatedByToPosts extends BaseMigration
{ {
#[Override]
public function up(): void public function up(): void
{ {
$prefix = $this->db->getPrefix(); $prefix = $this->db->getPrefix();
...@@ -33,11 +36,12 @@ class AddCreatedByToPosts extends BaseMigration ...@@ -33,11 +36,12 @@ class AddCreatedByToPosts extends BaseMigration
'id', 'id',
'', '',
'CASCADE', 'CASCADE',
$prefix . 'fediverse_posts_created_by_foreign' $prefix . 'fediverse_posts_created_by_foreign',
); );
$this->forge->processIndexes('fediverse_posts'); $this->forge->processIndexes('fediverse_posts');
} }
#[Override]
public function down(): void public function down(): void
{ {
$prefix = $this->db->getPrefix(); $prefix = $this->db->getPrefix();
......
...@@ -4,8 +4,11 @@ declare(strict_types=1); ...@@ -4,8 +4,11 @@ declare(strict_types=1);
namespace App\Database\Migrations; namespace App\Database\Migrations;
use Override;
class AddFullTextSearchIndexes extends BaseMigration class AddFullTextSearchIndexes extends BaseMigration
{ {
#[Override]
public function up(): void public function up(): void
{ {
$prefix = $this->db->getPrefix(); $prefix = $this->db->getPrefix();
...@@ -31,6 +34,7 @@ class AddFullTextSearchIndexes extends BaseMigration ...@@ -31,6 +34,7 @@ class AddFullTextSearchIndexes extends BaseMigration
$this->db->query($createQuery); $this->db->query($createQuery);
} }
#[Override]
public function down(): void public function down(): void
{ {
$prefix = $this->db->getPrefix(); $prefix = $this->db->getPrefix();
......
...@@ -4,8 +4,11 @@ declare(strict_types=1); ...@@ -4,8 +4,11 @@ declare(strict_types=1);
namespace App\Database\Migrations; namespace App\Database\Migrations;
use Override;
class AddEpisodePreviewId extends BaseMigration class AddEpisodePreviewId extends BaseMigration
{ {
#[Override]
public function up(): void public function up(): void
{ {
$fields = [ $fields = [
...@@ -28,6 +31,7 @@ class AddEpisodePreviewId extends BaseMigration ...@@ -28,6 +31,7 @@ class AddEpisodePreviewId extends BaseMigration
$this->db->query($uniquePreviewId); $this->db->query($uniquePreviewId);
} }
#[Override]
public function down(): void public function down(): void
{ {
$fields = ['preview_id']; $fields = ['preview_id'];
......
...@@ -12,8 +12,11 @@ declare(strict_types=1); ...@@ -12,8 +12,11 @@ declare(strict_types=1);
namespace App\Database\Migrations; namespace App\Database\Migrations;
use Override;
class AddPodcastsOwnerEmailRemovedFromFeed extends BaseMigration class AddPodcastsOwnerEmailRemovedFromFeed extends BaseMigration
{ {
#[Override]
public function up(): void public function up(): void
{ {
$fields = [ $fields = [
...@@ -28,6 +31,7 @@ class AddPodcastsOwnerEmailRemovedFromFeed extends BaseMigration ...@@ -28,6 +31,7 @@ class AddPodcastsOwnerEmailRemovedFromFeed extends BaseMigration
$this->forge->addColumn('podcasts', $fields); $this->forge->addColumn('podcasts', $fields);
} }
#[Override]
public function down(): void public function down(): void
{ {
$fields = ['is_owner_email_removed_from_feed']; $fields = ['is_owner_email_removed_from_feed'];
......
...@@ -12,8 +12,11 @@ declare(strict_types=1); ...@@ -12,8 +12,11 @@ declare(strict_types=1);
namespace App\Database\Migrations; namespace App\Database\Migrations;
use Override;
class AddPodcastsMediumField extends BaseMigration class AddPodcastsMediumField extends BaseMigration
{ {
#[Override]
public function up(): void public function up(): void
{ {
$fields = [ $fields = [
...@@ -28,6 +31,7 @@ class AddPodcastsMediumField extends BaseMigration ...@@ -28,6 +31,7 @@ class AddPodcastsMediumField extends BaseMigration
$this->forge->addColumn('podcasts', $fields); $this->forge->addColumn('podcasts', $fields);
} }
#[Override]
public function down(): void public function down(): void
{ {
$fields = ['medium']; $fields = ['medium'];
......
<?php
declare(strict_types=1);
/**
* Class AddPodcastsVerifyTxtField adds 1 field to podcast table in database to support podcast:txt tag
*
* @copyright 2024 Ad Aures
* @license https://www.gnu.org/licenses/agpl-3.0.en.html AGPL3
* @link https://castopod.org/
*/
namespace App\Database\Migrations;
use Override;
class AddPodcastsVerifyTxtField extends BaseMigration
{
#[Override]
public function up(): void
{
$fields = [
'verify_txt' => [
'type' => 'TEXT',
'null' => true,
'after' => 'location_osm',
],
];
$this->forge->addColumn('podcasts', $fields);
}
#[Override]
public function down(): void
{
$this->forge->dropColumn('podcasts', 'verify_txt');
}
}
<?php
declare(strict_types=1);
namespace App\Database\Migrations;
use CodeIgniter\Database\Migration;
use Override;
class RefactorPlatforms extends Migration
{
#[Override]
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');
}
#[Override]
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');
}
}
<?php
declare(strict_types=1);
namespace App\Database\Migrations;
use CodeIgniter\Database\Migration;
use Override;
/**
* CodeIgniter 4.5.1 introduces new DataCaster class that breaks deserialization of import queue tasks.
* This just removes them altogether.
*/
class ClearImportQueue extends Migration
{
#[Override]
public function up(): void
{
service('settings')->forget('Import.queue');
}
#[Override]
public function down(): void
{
// nothing
}
}
<?php
declare(strict_types=1);
namespace App\Database\Migrations;
use CodeIgniter\Database\Migration;
class AddEpisodeDownloadsCount extends Migration
{
public function up(): void
{
$fields = [
'downloads_count' => [
'type' => 'INT',
'unsigned' => true,
'default' => 0,
'after' => 'is_published_on_hubs',
],
];
$this->forge->addColumn('episodes', $fields);
}
public function down(): void
{
$this->forge->dropColumn('episodes', 'downloads_count');
}
}
<?php
declare(strict_types=1);
/**
* Class AddPodcastsMediumField adds medium field to podcast 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\Database\Migrations;
use Override;
class DropDeprecatedPodcastsFields extends BaseMigration
{
#[Override]
public function up(): void
{
// TODO: migrate data
$this->forge->dropColumn(
'podcasts',
'episode_description_footer_markdown,episode_description_footer_html,is_owner_email_removed_from_feed,medium,payment_pointer,verify_txt,custom_rss,partner_id,partner_link_url,partner_image_url',
);
}
#[Override]
public function down(): void
{
$fields = [
'episode_description_footer_markdown' => [
'type' => 'TEXT',
'null' => true,
],
'episode_description_footer_html' => [
'type' => 'TEXT',
'null' => true,
],
'is_owner_email_removed_from_feed' => [
'type' => 'BOOLEAN',
'null' => false,
'default' => 0,
'after' => 'owner_email',
],
'medium' => [
'type' => "ENUM('podcast','music','audiobook')",
'null' => false,
'default' => 'podcast',
'after' => 'type',
],
'payment_pointer' => [
'type' => 'VARCHAR',
'constraint' => 128,
'comment' => 'Wallet address for Web Monetization payments',
'null' => true,
],
'verify_txt' => [
'type' => 'TEXT',
'null' => true,
'after' => 'location_osm',
],
'custom_rss' => [
'type' => 'JSON',
'null' => true,
],
'partner_id' => [
'type' => 'VARCHAR',
'constraint' => 32,
'null' => true,
],
'partner_link_url' => [
'type' => 'VARCHAR',
'constraint' => 512,
'null' => true,
],
'partner_image_url' => [
'type' => 'VARCHAR',
'constraint' => 512,
'null' => true,
],
];
$this->forge->addColumn('podcasts', $fields);
}
}
<?php
declare(strict_types=1);
/**
* Class AddPodcastsMediumField adds medium field to podcast 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\Database\Migrations;
use Override;
class DropDeprecatedEpisodesFields extends BaseMigration
{
#[Override]
public function up(): void
{
$this->forge->dropColumn('episodes', 'custom_rss');
}
#[Override]
public function down(): void
{
$fields = [
'custom_rss' => [
'type' => 'JSON',
'null' => true,
],
];
$this->forge->addColumn('episodes', $fields);
}
}
...@@ -14,6 +14,7 @@ namespace App\Database\Migrations; ...@@ -14,6 +14,7 @@ namespace App\Database\Migrations;
use CodeIgniter\Database\BaseConnection; use CodeIgniter\Database\BaseConnection;
use CodeIgniter\Database\Migration; use CodeIgniter\Database\Migration;
use Override;
class BaseMigration extends Migration class BaseMigration extends Migration
{ {
...@@ -24,10 +25,12 @@ class BaseMigration extends Migration ...@@ -24,10 +25,12 @@ class BaseMigration extends Migration
*/ */
protected $db; protected $db;
#[Override]
public function up(): void public function up(): void
{ {
} }
#[Override]
public function down(): void public function down(): void
{ {
} }
......
...@@ -13,13 +13,14 @@ declare(strict_types=1); ...@@ -13,13 +13,14 @@ declare(strict_types=1);
namespace App\Database\Seeds; namespace App\Database\Seeds;
use CodeIgniter\Database\Seeder; use CodeIgniter\Database\Seeder;
use Override;
class AppSeeder extends Seeder class AppSeeder extends Seeder
{ {
#[Override]
public function run(): void public function run(): void
{ {
$this->call('CategorySeeder'); $this->call('CategorySeeder');
$this->call('LanguageSeeder'); $this->call('LanguageSeeder');
$this->call('PlatformSeeder');
} }
} }
...@@ -13,9 +13,11 @@ declare(strict_types=1); ...@@ -13,9 +13,11 @@ declare(strict_types=1);
namespace App\Database\Seeds; namespace App\Database\Seeds;
use CodeIgniter\Database\Seeder; use CodeIgniter\Database\Seeder;
use Override;
class CategorySeeder extends Seeder class CategorySeeder extends Seeder
{ {
#[Override]
public function run(): void public function run(): void
{ {
$data = [ $data = [
......
...@@ -3,26 +3,25 @@ ...@@ -3,26 +3,25 @@
declare(strict_types=1); declare(strict_types=1);
/** /**
* Class AppSeeder Calls all required seeders for castopod to work properly
*
* @copyright 2020 Ad Aures * @copyright 2020 Ad Aures
* @license https://www.gnu.org/licenses/agpl-3.0.en.html AGPL3 * @license https://www.gnu.org/licenses/agpl-3.0.en.html AGPL3
* @link https://castopod.org/ * @link https://castopod.org/
*/ */
namespace App\Controllers; namespace App\Database\Seeds;
use App\Models\PlatformModel; use CodeIgniter\Database\Seeder;
use CodeIgniter\Controller; use Override;
use CodeIgniter\HTTP\ResponseInterface;
/* class DevSeeder extends Seeder
* Provide public access to all platforms so that they can be exported
*/
class PlatformController extends Controller
{ {
public function index(): ResponseInterface #[Override]
public function run(): void
{ {
$model = new PlatformModel(); $this->call('CategorySeeder');
$this->call('LanguageSeeder');
return $this->response->setJSON($model->getPlatforms()); $this->call('DevSuperadminSeeder');
} }
} }
...@@ -13,37 +13,38 @@ declare(strict_types=1); ...@@ -13,37 +13,38 @@ declare(strict_types=1);
namespace App\Database\Seeds; namespace App\Database\Seeds;
use CodeIgniter\Database\Seeder; use CodeIgniter\Database\Seeder;
use CodeIgniter\Shield\Entities\User;
use Modules\Auth\Models\UserModel;
use Override;
class TestSeeder extends Seeder class DevSuperadminSeeder extends Seeder
{ {
#[Override]
public function run(): void public function run(): void
{ {
helper('setting'); if ((new UserModel())->where('is_owner', true)->first() instanceof User) {
return;
}
/** /**
* Inserts an owner with the following credentials: admin: `admin@example.com` password: `AGUehL3P` * Inserts an owner with the following credentials: admin: `admin@example.com` password: `castopod`
*/ */
$this->db->table('users')
->insert([ // Get the User Provider (UserModel by default)
'id' => 1, $users = auth()
'username' => 'admin', ->getProvider();
'is_owner' => 1,
]); $user = new User([
'username' => 'admin',
$this->db->table('auth_identities') 'email' => 'admin@castopod.local',
->insert([ 'password' => 'castopod',
'id' => 1, 'is_owner' => true,
'user_id' => 1, ]);
'type' => 'email_password', $users->save($user);
'secret' => 'admin@example.com',
'secret2' => '$2y$10$TXJEHX/djW8jtzgpDVf7dOOCGo5rv1uqtAYWdwwwkttQcDkAeB2.6', // To get the complete user object with ID, we need to get from the database
]); $user = $users->findById($users->getInsertID());
$this->db $user->addGroup(setting('AuthGroups.mostPowerfulGroup'));
->table('auth_groups_users')
->insert([
'user_id' => 1,
'group' => setting('AuthGroups.mostPowerfulGroup'),
]);
} }
} }
...@@ -20,9 +20,11 @@ use CodeIgniter\Database\Seeder; ...@@ -20,9 +20,11 @@ use CodeIgniter\Database\Seeder;
use Exception; use Exception;
use GeoIp2\Database\Reader; use GeoIp2\Database\Reader;
use GeoIp2\Exception\AddressNotFoundException; use GeoIp2\Exception\AddressNotFoundException;
use Override;
class FakePodcastsAnalyticsSeeder extends Seeder class FakePodcastsAnalyticsSeeder extends Seeder
{ {
#[Override]
public function run(): void public function run(): void
{ {
$jsonUserAgents = json_decode( $jsonUserAgents = json_decode(
...@@ -77,34 +79,32 @@ class FakePodcastsAnalyticsSeeder extends Seeder ...@@ -77,34 +79,32 @@ class FakePodcastsAnalyticsSeeder extends Seeder
for ( for (
$lineNumber = 0; $lineNumber = 0;
$lineNumber < rand(1, (int) $probability1); $lineNumber < random_int(1, (int) $probability1);
++$lineNumber ++$lineNumber
) { ) {
$probability2 = floor(exp(6 - $age / 20)) + 10; $probability2 = floor(exp(6 - $age / 20)) + 10;
$player = $player =
$jsonUserAgents[ $jsonUserAgents[
rand(1, count($jsonUserAgents) - 1) random_int(1, count($jsonUserAgents) - 1)
]; ];
$service = $service =
$jsonRSSUserAgents[ $jsonRSSUserAgents[
rand(1, count($jsonRSSUserAgents) - 1) random_int(1, count($jsonRSSUserAgents) - 1)
]['slug']; ]['slug'];
$app = isset($player['app']) ? $player['app'] : ''; $app = $player['app'] ?? '';
$device = isset($player['device']) $device = $player['device'] ?? '';
? $player['device'] $os = $player['os'] ?? '';
: ''; $isBot = $player['bot'] ?? 0;
$os = isset($player['os']) ? $player['os'] : '';
$isBot = isset($player['bot']) ? $player['bot'] : 0;
$fakeIp = $fakeIp =
rand(0, 255) . random_int(0, 255) .
'.' . '.' .
rand(0, 255) . random_int(0, 255) .
'.' . '.' .
rand(0, 255) . random_int(0, 255) .
'.' . '.' .
rand(0, 255); random_int(0, 255);
$cityReader = new Reader(WRITEPATH . 'uploads/GeoLite2-City/GeoLite2-City.mmdb'); $cityReader = new Reader(WRITEPATH . 'uploads/GeoLite2-City/GeoLite2-City.mmdb');
...@@ -115,9 +115,7 @@ class FakePodcastsAnalyticsSeeder extends Seeder ...@@ -115,9 +115,7 @@ class FakePodcastsAnalyticsSeeder extends Seeder
try { try {
$city = $cityReader->city($fakeIp); $city = $cityReader->city($fakeIp);
$countryCode = $city->country->isoCode === null $countryCode = $city->country->isoCode ?? 'N/A';
? 'N/A'
: $city->country->isoCode;
$regionCode = $city->subdivisions === [] $regionCode = $city->subdivisions === []
? 'N/A' ? 'N/A'
...@@ -128,20 +126,20 @@ class FakePodcastsAnalyticsSeeder extends Seeder ...@@ -128,20 +126,20 @@ class FakePodcastsAnalyticsSeeder extends Seeder
//Bad luck, bad IP, nothing to do. //Bad luck, bad IP, nothing to do.
} }
$hits = rand(0, (int) $probability2); $hits = random_int(0, (int) $probability2);
$analyticsPodcasts[] = [ $analyticsPodcasts[] = [
'podcast_id' => $podcast->id, 'podcast_id' => $podcast->id,
'date' => date('Y-m-d', $date), 'date' => date('Y-m-d', $date),
'duration' => rand(60, 3600), 'duration' => random_int(60, 3600),
'bandwidth' => rand(1000000, 10000000), 'bandwidth' => random_int(1000000, 10000000),
'hits' => $hits, 'hits' => $hits,
'unique_listeners' => $hits, 'unique_listeners' => $hits,
]; ];
$analyticsPodcastsByHour[] = [ $analyticsPodcastsByHour[] = [
'podcast_id' => $podcast->id, 'podcast_id' => $podcast->id,
'date' => date('Y-m-d', $date), 'date' => date('Y-m-d', $date),
'hour' => rand(0, 23), 'hour' => random_int(0, 23),
'hits' => $hits, 'hits' => $hits,
]; ];
$analyticsPodcastsByCountry[] = [ $analyticsPodcastsByCountry[] = [
......