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 1749 additions and 2102 deletions
......@@ -5,7 +5,7 @@ declare(strict_types=1);
/**
* Class CategorySeeder Inserts values in categories table in database
*
* @copyright 2020 Podlibre
* @copyright 2020 Ad Aures
* @license https://www.gnu.org/licenses/agpl-3.0.en.html AGPL3
* @link https://castopod.org/
*/
......@@ -13,787 +13,791 @@ declare(strict_types=1);
namespace App\Database\Seeds;
use CodeIgniter\Database\Seeder;
use Override;
class CategorySeeder extends Seeder
{
#[Override]
public function run(): void
{
$data = [
[
'id' => 1,
'parent_id' => null,
'code' => 'arts',
'apple_category' => 'Arts',
'id' => 1,
'parent_id' => null,
'code' => 'arts',
'apple_category' => 'Arts',
'google_category' => 'Arts',
],
[
'id' => 2,
'parent_id' => null,
'code' => 'business',
'apple_category' => 'Business',
'id' => 2,
'parent_id' => null,
'code' => 'business',
'apple_category' => 'Business',
'google_category' => 'Business',
],
[
'id' => 3,
'parent_id' => null,
'code' => 'comedy',
'apple_category' => 'Comedy',
'id' => 3,
'parent_id' => null,
'code' => 'comedy',
'apple_category' => 'Comedy',
'google_category' => 'Comedy',
],
[
'id' => 4,
'parent_id' => null,
'code' => 'education',
'apple_category' => 'Education',
'id' => 4,
'parent_id' => null,
'code' => 'education',
'apple_category' => 'Education',
'google_category' => 'Education',
],
[
'id' => 5,
'parent_id' => null,
'code' => 'fiction',
'apple_category' => 'Fiction',
'id' => 5,
'parent_id' => null,
'code' => 'fiction',
'apple_category' => 'Fiction',
'google_category' => '',
],
[
'id' => 6,
'parent_id' => null,
'code' => 'government',
'apple_category' => 'Government',
'id' => 6,
'parent_id' => null,
'code' => 'government',
'apple_category' => 'Government',
'google_category' => 'Government & Organizations',
],
[
'id' => 7,
'parent_id' => null,
'code' => 'health_and_fitness',
'apple_category' => 'Health & Fitness',
'id' => 7,
'parent_id' => null,
'code' => 'health_and_fitness',
'apple_category' => 'Health & Fitness',
'google_category' => 'Health',
],
[
'id' => 8,
'parent_id' => null,
'code' => 'history',
'apple_category' => 'History',
'id' => 8,
'parent_id' => null,
'code' => 'history',
'apple_category' => 'History',
'google_category' => '',
],
[
'id' => 9,
'parent_id' => null,
'code' => 'kids_and_family',
'apple_category' => 'Kids & Family',
'id' => 9,
'parent_id' => null,
'code' => 'kids_and_family',
'apple_category' => 'Kids & Family',
'google_category' => 'Kids & Family',
],
[
'id' => 10,
'parent_id' => null,
'code' => 'leisure',
'apple_category' => 'Leisure',
'id' => 10,
'parent_id' => null,
'code' => 'leisure',
'apple_category' => 'Leisure',
'google_category' => 'Games & Hobbies',
],
[
'id' => 11,
'parent_id' => null,
'code' => 'music',
'apple_category' => 'Music',
'id' => 11,
'parent_id' => null,
'code' => 'music',
'apple_category' => 'Music',
'google_category' => 'Music',
],
[
'id' => 12,
'parent_id' => null,
'code' => 'news',
'apple_category' => 'News',
'id' => 12,
'parent_id' => null,
'code' => 'news',
'apple_category' => 'News',
'google_category' => 'News & Politics',
],
[
'id' => 13,
'parent_id' => null,
'code' => 'religion_and_spirituality',
'apple_category' => 'Religion & Spirituality',
'id' => 13,
'parent_id' => null,
'code' => 'religion_and_spirituality',
'apple_category' => 'Religion & Spirituality',
'google_category' => 'Religion & Spirituality',
],
[
'id' => 14,
'parent_id' => null,
'code' => 'science',
'apple_category' => 'Science',
'id' => 14,
'parent_id' => null,
'code' => 'science',
'apple_category' => 'Science',
'google_category' => 'Science & Medicine',
],
[
'id' => 15,
'parent_id' => null,
'code' => 'society_and_culture',
'apple_category' => 'Society & Culture',
'id' => 15,
'parent_id' => null,
'code' => 'society_and_culture',
'apple_category' => 'Society & Culture',
'google_category' => 'Society & Culture',
],
[
'id' => 16,
'parent_id' => null,
'code' => 'sports',
'apple_category' => 'Sports',
'id' => 16,
'parent_id' => null,
'code' => 'sports',
'apple_category' => 'Sports',
'google_category' => 'Sports & Recreation',
],
[
'id' => 17,
'parent_id' => null,
'code' => 'technology',
'apple_category' => 'Technology',
'id' => 17,
'parent_id' => null,
'code' => 'technology',
'apple_category' => 'Technology',
'google_category' => 'Technology',
],
[
'id' => 18,
'parent_id' => null,
'code' => 'true_crime',
'apple_category' => 'True Crime',
'id' => 18,
'parent_id' => null,
'code' => 'true_crime',
'apple_category' => 'True Crime',
'google_category' => '',
],
[
'id' => 19,
'parent_id' => null,
'code' => 'tv_and_film',
'apple_category' => 'TV & Film',
'id' => 19,
'parent_id' => null,
'code' => 'tv_and_film',
'apple_category' => 'TV & Film',
'google_category' => 'TV & Film',
],
[
'id' => 20,
'parent_id' => 1,
'code' => 'books',
'apple_category' => 'Books',
'id' => 20,
'parent_id' => 1,
'code' => 'books',
'apple_category' => 'Books',
'google_category' => '',
],
[
'id' => 21,
'parent_id' => 1,
'code' => 'design',
'apple_category' => 'Design',
'id' => 21,
'parent_id' => 1,
'code' => 'design',
'apple_category' => 'Design',
'google_category' => '',
],
[
'id' => 22,
'parent_id' => 1,
'code' => 'fashion_and_beauty',
'apple_category' => 'Fashion & Beauty',
'id' => 22,
'parent_id' => 1,
'code' => 'fashion_and_beauty',
'apple_category' => 'Fashion & Beauty',
'google_category' => '',
],
[
'id' => 23,
'parent_id' => 1,
'code' => 'food',
'apple_category' => 'Food',
'id' => 23,
'parent_id' => 1,
'code' => 'food',
'apple_category' => 'Food',
'google_category' => '',
],
[
'id' => 24,
'parent_id' => 1,
'code' => 'performing_arts',
'apple_category' => 'Performing Arts',
'id' => 24,
'parent_id' => 1,
'code' => 'performing_arts',
'apple_category' => 'Performing Arts',
'google_category' => '',
],
[
'id' => 25,
'parent_id' => 1,
'code' => 'visual_arts',
'apple_category' => 'Visual Arts',
'id' => 25,
'parent_id' => 1,
'code' => 'visual_arts',
'apple_category' => 'Visual Arts',
'google_category' => '',
],
[
'id' => 26,
'parent_id' => 2,
'code' => 'careers',
'apple_category' => 'Careers',
'id' => 26,
'parent_id' => 2,
'code' => 'careers',
'apple_category' => 'Careers',
'google_category' => '',
],
[
'id' => 27,
'parent_id' => 2,
'code' => 'entrepreneurship',
'apple_category' => 'Entrepreneurship',
'id' => 27,
'parent_id' => 2,
'code' => 'entrepreneurship',
'apple_category' => 'Entrepreneurship',
'google_category' => '',
],
[
'id' => 28,
'parent_id' => 2,
'code' => 'investing',
'apple_category' => 'Investing',
'id' => 28,
'parent_id' => 2,
'code' => 'investing',
'apple_category' => 'Investing',
'google_category' => '',
],
[
'id' => 29,
'parent_id' => 2,
'code' => 'management',
'apple_category' => 'Management',
'id' => 29,
'parent_id' => 2,
'code' => 'management',
'apple_category' => 'Management',
'google_category' => '',
],
[
'id' => 30,
'parent_id' => 2,
'code' => 'marketing',
'apple_category' => 'Marketing',
'id' => 30,
'parent_id' => 2,
'code' => 'marketing',
'apple_category' => 'Marketing',
'google_category' => '',
],
[
'id' => 31,
'parent_id' => 2,
'code' => 'non_profit',
'apple_category' => 'Non-Profit',
'id' => 31,
'parent_id' => 2,
'code' => 'non_profit',
'apple_category' => 'Non-Profit',
'google_category' => '',
],
[
'id' => 32,
'parent_id' => 3,
'code' => 'comedy_interviews',
'apple_category' => 'Comedy Interviews',
'id' => 32,
'parent_id' => 3,
'code' => 'comedy_interviews',
'apple_category' => 'Comedy Interviews',
'google_category' => '',
],
[
'id' => 33,
'parent_id' => 3,
'code' => 'improv',
'apple_category' => 'Improv',
'id' => 33,
'parent_id' => 3,
'code' => 'improv',
'apple_category' => 'Improv',
'google_category' => '',
],
[
'id' => 34,
'parent_id' => 3,
'code' => 'stand_up',
'apple_category' => 'Stand-Up',
'id' => 34,
'parent_id' => 3,
'code' => 'stand_up',
'apple_category' => 'Stand-Up',
'google_category' => '',
],
[
'id' => 35,
'parent_id' => 4,
'code' => 'courses',
'apple_category' => 'Courses',
'id' => 35,
'parent_id' => 4,
'code' => 'courses',
'apple_category' => 'Courses',
'google_category' => '',
],
[
'id' => 36,
'parent_id' => 4,
'code' => 'how_to',
'apple_category' => 'How To',
'id' => 36,
'parent_id' => 4,
'code' => 'how_to',
'apple_category' => 'How To',
'google_category' => '',
],
[
'id' => 37,
'parent_id' => 4,
'code' => 'language_learning',
'apple_category' => 'Language Learning',
'id' => 37,
'parent_id' => 4,
'code' => 'language_learning',
'apple_category' => 'Language Learning',
'google_category' => '',
],
[
'id' => 38,
'parent_id' => 4,
'code' => 'self_improvement',
'apple_category' => 'Self-Improvement',
'id' => 38,
'parent_id' => 4,
'code' => 'self_improvement',
'apple_category' => 'Self-Improvement',
'google_category' => '',
],
[
'id' => 39,
'parent_id' => 5,
'code' => 'comedy_fiction',
'apple_category' => 'Comedy Fiction',
'id' => 39,
'parent_id' => 5,
'code' => 'comedy_fiction',
'apple_category' => 'Comedy Fiction',
'google_category' => '',
],
[
'id' => 40,
'parent_id' => 5,
'code' => 'drama',
'apple_category' => 'Drama',
'id' => 40,
'parent_id' => 5,
'code' => 'drama',
'apple_category' => 'Drama',
'google_category' => '',
],
[
'id' => 41,
'parent_id' => 5,
'code' => 'science_fiction',
'apple_category' => 'Science Fiction',
'id' => 41,
'parent_id' => 5,
'code' => 'science_fiction',
'apple_category' => 'Science Fiction',
'google_category' => '',
],
[
'id' => 42,
'parent_id' => 7,
'code' => 'alternative_health',
'apple_category' => 'Alternative Health',
'id' => 42,
'parent_id' => 7,
'code' => 'alternative_health',
'apple_category' => 'Alternative Health',
'google_category' => '',
],
[
'id' => 43,
'parent_id' => 7,
'code' => 'fitness',
'apple_category' => 'Fitness',
'id' => 43,
'parent_id' => 7,
'code' => 'fitness',
'apple_category' => 'Fitness',
'google_category' => '',
],
[
'id' => 44,
'parent_id' => 7,
'code' => 'medicine',
'apple_category' => 'Medicine',
'id' => 44,
'parent_id' => 7,
'code' => 'medicine',
'apple_category' => 'Medicine',
'google_category' => '',
],
[
'id' => 45,
'parent_id' => 7,
'code' => 'mental_health',
'apple_category' => 'Mental Health',
'id' => 45,
'parent_id' => 7,
'code' => 'mental_health',
'apple_category' => 'Mental Health',
'google_category' => '',
],
[
'id' => 46,
'parent_id' => 7,
'code' => 'nutrition',
'apple_category' => 'Nutrition',
'id' => 46,
'parent_id' => 7,
'code' => 'nutrition',
'apple_category' => 'Nutrition',
'google_category' => '',
],
[
'id' => 47,
'parent_id' => 7,
'code' => 'sexuality',
'apple_category' => 'Sexuality',
'id' => 47,
'parent_id' => 7,
'code' => 'sexuality',
'apple_category' => 'Sexuality',
'google_category' => '',
],
[
'id' => 48,
'parent_id' => 9,
'code' => 'education_for_kids',
'apple_category' => 'Education for Kids',
'id' => 48,
'parent_id' => 9,
'code' => 'education_for_kids',
'apple_category' => 'Education for Kids',
'google_category' => '',
],
[
'id' => 49,
'parent_id' => 9,
'code' => 'parenting',
'apple_category' => 'Parenting',
'id' => 49,
'parent_id' => 9,
'code' => 'parenting',
'apple_category' => 'Parenting',
'google_category' => '',
],
[
'id' => 50,
'parent_id' => 9,
'code' => 'pets_and_animals',
'apple_category' => 'Pets & Animals',
'id' => 50,
'parent_id' => 9,
'code' => 'pets_and_animals',
'apple_category' => 'Pets & Animals',
'google_category' => '',
],
[
'id' => 51,
'parent_id' => 9,
'code' => 'stories_for_kids',
'apple_category' => 'Stories for Kids',
'id' => 51,
'parent_id' => 9,
'code' => 'stories_for_kids',
'apple_category' => 'Stories for Kids',
'google_category' => '',
],
[
'id' => 52,
'parent_id' => 10,
'code' => 'animation_and_manga',
'apple_category' => 'Animation & Manga',
'id' => 52,
'parent_id' => 10,
'code' => 'animation_and_manga',
'apple_category' => 'Animation & Manga',
'google_category' => '',
],
[
'id' => 53,
'parent_id' => 10,
'code' => 'automotive',
'apple_category' => 'Automotive',
'id' => 53,
'parent_id' => 10,
'code' => 'automotive',
'apple_category' => 'Automotive',
'google_category' => '',
],
[
'id' => 54,
'parent_id' => 10,
'code' => 'aviation',
'apple_category' => 'Aviation',
'id' => 54,
'parent_id' => 10,
'code' => 'aviation',
'apple_category' => 'Aviation',
'google_category' => '',
],
[
'id' => 55,
'parent_id' => 10,
'code' => 'crafts',
'apple_category' => 'Crafts',
'id' => 55,
'parent_id' => 10,
'code' => 'crafts',
'apple_category' => 'Crafts',
'google_category' => '',
],
[
'id' => 56,
'parent_id' => 10,
'code' => 'games',
'apple_category' => 'Games',
'id' => 56,
'parent_id' => 10,
'code' => 'games',
'apple_category' => 'Games',
'google_category' => '',
],
[
'id' => 57,
'parent_id' => 10,
'code' => 'hobbies',
'apple_category' => 'Hobbies',
'id' => 57,
'parent_id' => 10,
'code' => 'hobbies',
'apple_category' => 'Hobbies',
'google_category' => '',
],
[
'id' => 58,
'parent_id' => 10,
'code' => 'home_and_garden',
'apple_category' => 'Home & Garden',
'id' => 58,
'parent_id' => 10,
'code' => 'home_and_garden',
'apple_category' => 'Home & Garden',
'google_category' => '',
],
[
'id' => 59,
'parent_id' => 10,
'code' => 'video_games',
'apple_category' => 'Video Games',
'id' => 59,
'parent_id' => 10,
'code' => 'video_games',
'apple_category' => 'Video Games',
'google_category' => '',
],
[
'id' => 60,
'parent_id' => 11,
'code' => 'music_commentary',
'apple_category' => 'Music Commentary',
'id' => 60,
'parent_id' => 11,
'code' => 'music_commentary',
'apple_category' => 'Music Commentary',
'google_category' => '',
],
[
'id' => 61,
'parent_id' => 11,
'code' => 'music_history',
'apple_category' => 'Music History',
'id' => 61,
'parent_id' => 11,
'code' => 'music_history',
'apple_category' => 'Music History',
'google_category' => '',
],
[
'id' => 62,
'parent_id' => 11,
'code' => 'music_interviews',
'apple_category' => 'Music Interviews',
'id' => 62,
'parent_id' => 11,
'code' => 'music_interviews',
'apple_category' => 'Music Interviews',
'google_category' => '',
],
[
'id' => 63,
'parent_id' => 12,
'code' => 'business_news',
'apple_category' => 'Business News',
'id' => 63,
'parent_id' => 12,
'code' => 'business_news',
'apple_category' => 'Business News',
'google_category' => '',
],
[
'id' => 64,
'parent_id' => 12,
'code' => 'daily_news',
'apple_category' => 'Daily News',
'id' => 64,
'parent_id' => 12,
'code' => 'daily_news',
'apple_category' => 'Daily News',
'google_category' => '',
],
[
'id' => 65,
'parent_id' => 12,
'code' => 'entertainment_news',
'apple_category' => 'Entertainment News',
'id' => 65,
'parent_id' => 12,
'code' => 'entertainment_news',
'apple_category' => 'Entertainment News',
'google_category' => '',
],
[
'id' => 66,
'parent_id' => 12,
'code' => 'news_commentary',
'apple_category' => 'News Commentary',
'id' => 66,
'parent_id' => 12,
'code' => 'news_commentary',
'apple_category' => 'News Commentary',
'google_category' => '',
],
[
'id' => 67,
'parent_id' => 12,
'code' => 'politics',
'apple_category' => 'Politics',
'id' => 67,
'parent_id' => 12,
'code' => 'politics',
'apple_category' => 'Politics',
'google_category' => '',
],
[
'id' => 68,
'parent_id' => 12,
'code' => 'sports_news',
'apple_category' => 'Sports News',
'id' => 68,
'parent_id' => 12,
'code' => 'sports_news',
'apple_category' => 'Sports News',
'google_category' => '',
],
[
'id' => 69,
'parent_id' => 12,
'code' => 'tech_news',
'apple_category' => 'Tech News',
'id' => 69,
'parent_id' => 12,
'code' => 'tech_news',
'apple_category' => 'Tech News',
'google_category' => '',
],
[
'id' => 70,
'parent_id' => 13,
'code' => 'buddhism',
'apple_category' => 'Buddhism',
'id' => 70,
'parent_id' => 13,
'code' => 'buddhism',
'apple_category' => 'Buddhism',
'google_category' => '',
],
[
'id' => 71,
'parent_id' => 13,
'code' => 'christianity',
'apple_category' => 'Christianity',
'id' => 71,
'parent_id' => 13,
'code' => 'christianity',
'apple_category' => 'Christianity',
'google_category' => '',
],
[
'id' => 72,
'parent_id' => 13,
'code' => 'hinduism',
'apple_category' => 'Hinduism',
'id' => 72,
'parent_id' => 13,
'code' => 'hinduism',
'apple_category' => 'Hinduism',
'google_category' => '',
],
[
'id' => 73,
'parent_id' => 13,
'code' => 'islam',
'apple_category' => 'Islam',
'id' => 73,
'parent_id' => 13,
'code' => 'islam',
'apple_category' => 'Islam',
'google_category' => '',
],
[
'id' => 74,
'parent_id' => 13,
'code' => 'judaism',
'apple_category' => 'Judaism',
'id' => 74,
'parent_id' => 13,
'code' => 'judaism',
'apple_category' => 'Judaism',
'google_category' => '',
],
[
'id' => 75,
'parent_id' => 13,
'code' => 'religion',
'apple_category' => 'Religion',
'id' => 75,
'parent_id' => 13,
'code' => 'religion',
'apple_category' => 'Religion',
'google_category' => '',
],
[
'id' => 76,
'parent_id' => 13,
'code' => 'spirituality',
'apple_category' => 'Spirituality',
'id' => 76,
'parent_id' => 13,
'code' => 'spirituality',
'apple_category' => 'Spirituality',
'google_category' => '',
],
[
'id' => 77,
'parent_id' => 14,
'code' => 'astronomy',
'apple_category' => 'Astronomy',
'id' => 77,
'parent_id' => 14,
'code' => 'astronomy',
'apple_category' => 'Astronomy',
'google_category' => '',
],
[
'id' => 78,
'parent_id' => 14,
'code' => 'chemistry',
'apple_category' => 'Chemistry',
'id' => 78,
'parent_id' => 14,
'code' => 'chemistry',
'apple_category' => 'Chemistry',
'google_category' => '',
],
[
'id' => 79,
'parent_id' => 14,
'code' => 'earth_sciences',
'apple_category' => 'Earth Sciences',
'id' => 79,
'parent_id' => 14,
'code' => 'earth_sciences',
'apple_category' => 'Earth Sciences',
'google_category' => '',
],
[
'id' => 80,
'parent_id' => 14,
'code' => 'life_sciences',
'apple_category' => 'Life Sciences',
'id' => 80,
'parent_id' => 14,
'code' => 'life_sciences',
'apple_category' => 'Life Sciences',
'google_category' => '',
],
[
'id' => 81,
'parent_id' => 14,
'code' => 'mathematics',
'apple_category' => 'Mathematics',
'id' => 81,
'parent_id' => 14,
'code' => 'mathematics',
'apple_category' => 'Mathematics',
'google_category' => '',
],
[
'id' => 82,
'parent_id' => 14,
'code' => 'natural_sciences',
'apple_category' => 'Natural Sciences',
'id' => 82,
'parent_id' => 14,
'code' => 'natural_sciences',
'apple_category' => 'Natural Sciences',
'google_category' => '',
],
[
'id' => 83,
'parent_id' => 14,
'code' => 'nature',
'apple_category' => 'Nature',
'id' => 83,
'parent_id' => 14,
'code' => 'nature',
'apple_category' => 'Nature',
'google_category' => '',
],
[
'id' => 84,
'parent_id' => 14,
'code' => 'physics',
'apple_category' => 'Physics',
'id' => 84,
'parent_id' => 14,
'code' => 'physics',
'apple_category' => 'Physics',
'google_category' => '',
],
[
'id' => 85,
'parent_id' => 14,
'code' => 'social_sciences',
'apple_category' => 'Social Sciences',
'id' => 85,
'parent_id' => 14,
'code' => 'social_sciences',
'apple_category' => 'Social Sciences',
'google_category' => '',
],
[
'id' => 86,
'parent_id' => 15,
'code' => 'documentary',
'apple_category' => 'Documentary',
'id' => 86,
'parent_id' => 15,
'code' => 'documentary',
'apple_category' => 'Documentary',
'google_category' => '',
],
[
'id' => 87,
'parent_id' => 15,
'code' => 'personal_journals',
'apple_category' => 'Personal Journals',
'id' => 87,
'parent_id' => 15,
'code' => 'personal_journals',
'apple_category' => 'Personal Journals',
'google_category' => '',
],
[
'id' => 88,
'parent_id' => 15,
'code' => 'philosophy',
'apple_category' => 'Philosophy',
'id' => 88,
'parent_id' => 15,
'code' => 'philosophy',
'apple_category' => 'Philosophy',
'google_category' => '',
],
[
'id' => 89,
'parent_id' => 15,
'code' => 'places_and_travel',
'apple_category' => 'Places & Travel',
'id' => 89,
'parent_id' => 15,
'code' => 'places_and_travel',
'apple_category' => 'Places & Travel',
'google_category' => '',
],
[
'id' => 90,
'parent_id' => 15,
'code' => 'relationships',
'apple_category' => 'Relationships',
'id' => 90,
'parent_id' => 15,
'code' => 'relationships',
'apple_category' => 'Relationships',
'google_category' => '',
],
[
'id' => 91,
'parent_id' => 16,
'code' => 'baseball',
'apple_category' => 'Baseball',
'id' => 91,
'parent_id' => 16,
'code' => 'baseball',
'apple_category' => 'Baseball',
'google_category' => '',
],
[
'id' => 92,
'parent_id' => 16,
'code' => 'basketball',
'apple_category' => 'Basketball',
'id' => 92,
'parent_id' => 16,
'code' => 'basketball',
'apple_category' => 'Basketball',
'google_category' => '',
],
[
'id' => 93,
'parent_id' => 16,
'code' => 'cricket',
'apple_category' => 'Cricket',
'id' => 93,
'parent_id' => 16,
'code' => 'cricket',
'apple_category' => 'Cricket',
'google_category' => '',
],
[
'id' => 94,
'parent_id' => 16,
'code' => 'fantasy_sports',
'apple_category' => 'Fantasy Sports',
'id' => 94,
'parent_id' => 16,
'code' => 'fantasy_sports',
'apple_category' => 'Fantasy Sports',
'google_category' => '',
],
[
'id' => 95,
'parent_id' => 16,
'code' => 'football',
'apple_category' => 'Football',
'id' => 95,
'parent_id' => 16,
'code' => 'football',
'apple_category' => 'Football',
'google_category' => '',
],
[
'id' => 96,
'parent_id' => 16,
'code' => 'golf',
'apple_category' => 'Golf',
'id' => 96,
'parent_id' => 16,
'code' => 'golf',
'apple_category' => 'Golf',
'google_category' => '',
],
[
'id' => 97,
'parent_id' => 16,
'code' => 'hockey',
'apple_category' => 'Hockey',
'id' => 97,
'parent_id' => 16,
'code' => 'hockey',
'apple_category' => 'Hockey',
'google_category' => '',
],
[
'id' => 98,
'parent_id' => 16,
'code' => 'rugby',
'apple_category' => 'Rugby',
'id' => 98,
'parent_id' => 16,
'code' => 'rugby',
'apple_category' => 'Rugby',
'google_category' => '',
],
[
'id' => 99,
'parent_id' => 16,
'code' => 'running',
'apple_category' => 'Running',
'id' => 99,
'parent_id' => 16,
'code' => 'running',
'apple_category' => 'Running',
'google_category' => '',
],
[
'id' => 100,
'parent_id' => 16,
'code' => 'soccer',
'apple_category' => 'Soccer',
'id' => 100,
'parent_id' => 16,
'code' => 'soccer',
'apple_category' => 'Soccer',
'google_category' => '',
],
[
'id' => 101,
'parent_id' => 16,
'code' => 'swimming',
'apple_category' => 'Swimming',
'id' => 101,
'parent_id' => 16,
'code' => 'swimming',
'apple_category' => 'Swimming',
'google_category' => '',
],
[
'id' => 102,
'parent_id' => 16,
'code' => 'tennis',
'apple_category' => 'Tennis',
'id' => 102,
'parent_id' => 16,
'code' => 'tennis',
'apple_category' => 'Tennis',
'google_category' => '',
],
[
'id' => 103,
'parent_id' => 16,
'code' => 'volleyball',
'apple_category' => 'Volleyball',
'id' => 103,
'parent_id' => 16,
'code' => 'volleyball',
'apple_category' => 'Volleyball',
'google_category' => '',
],
[
'id' => 104,
'parent_id' => 16,
'code' => 'wilderness',
'apple_category' => 'Wilderness',
'id' => 104,
'parent_id' => 16,
'code' => 'wilderness',
'apple_category' => 'Wilderness',
'google_category' => '',
],
[
'id' => 105,
'parent_id' => 16,
'code' => 'wrestling',
'apple_category' => 'Wrestling',
'id' => 105,
'parent_id' => 16,
'code' => 'wrestling',
'apple_category' => 'Wrestling',
'google_category' => '',
],
[
'id' => 106,
'parent_id' => 19,
'code' => 'after_shows',
'apple_category' => 'After Shows',
'id' => 106,
'parent_id' => 19,
'code' => 'after_shows',
'apple_category' => 'After Shows',
'google_category' => '',
],
[
'id' => 107,
'parent_id' => 19,
'code' => 'film_history',
'apple_category' => 'Film History',
'id' => 107,
'parent_id' => 19,
'code' => 'film_history',
'apple_category' => 'Film History',
'google_category' => '',
],
[
'id' => 108,
'parent_id' => 19,
'code' => 'film_interviews',
'apple_category' => 'Film Interviews',
'id' => 108,
'parent_id' => 19,
'code' => 'film_interviews',
'apple_category' => 'Film Interviews',
'google_category' => '',
],
[
'id' => 109,
'parent_id' => 19,
'code' => 'film_reviews',
'apple_category' => 'Film Reviews',
'id' => 109,
'parent_id' => 19,
'code' => 'film_reviews',
'apple_category' => 'Film Reviews',
'google_category' => '',
],
[
'id' => 110,
'parent_id' => 19,
'code' => 'tv_reviews',
'apple_category' => 'TV Reviews',
'id' => 110,
'parent_id' => 19,
'code' => 'tv_reviews',
'apple_category' => 'TV Reviews',
'google_category' => '',
],
];
$this->db
->table('categories')
->ignore(true)
->insertBatch($data);
foreach ($data as $categoryLine) {
$this->db
->table('categories')
->ignore(true)
->insert($categoryLine);
}
}
}
<?php
declare(strict_types=1);
/**
* Class AppSeeder Calls all required seeders for castopod to work properly
*
* @copyright 2020 Ad Aures
* @license https://www.gnu.org/licenses/agpl-3.0.en.html AGPL3
* @link https://castopod.org/
*/
namespace App\Database\Seeds;
use CodeIgniter\Database\Seeder;
use Override;
class DevSeeder extends Seeder
{
#[Override]
public function run(): void
{
$this->call('CategorySeeder');
$this->call('LanguageSeeder');
$this->call('DevSuperadminSeeder');
}
}
<?php
declare(strict_types=1);
/**
* Class TestSeeder Inserts a superadmin user in the database
*
* @copyright 2020 Ad Aures
* @license https://www.gnu.org/licenses/agpl-3.0.en.html AGPL3
* @link https://castopod.org/
*/
namespace App\Database\Seeds;
use CodeIgniter\Database\Seeder;
use CodeIgniter\Shield\Entities\User;
use Modules\Auth\Models\UserModel;
use Override;
class DevSuperadminSeeder extends Seeder
{
#[Override]
public function run(): void
{
if ((new UserModel())->where('is_owner', true)->first() instanceof User) {
return;
}
/**
* Inserts an owner with the following credentials: admin: `admin@example.com` password: `castopod`
*/
// Get the User Provider (UserModel by default)
$users = auth()
->getProvider();
$user = new User([
'username' => 'admin',
'email' => 'admin@castopod.local',
'password' => 'castopod',
'is_owner' => true,
]);
$users->save($user);
// To get the complete user object with ID, we need to get from the database
$user = $users->findById($users->getInsertID());
$user->addGroup(setting('AuthGroups.mostPowerfulGroup'));
}
}
......@@ -5,22 +5,26 @@ declare(strict_types=1);
/**
* Class FakePodcastsAnalyticsSeeder Inserts Fake Analytics in the database
*
* @copyright 2020 Podlibre
* @copyright 2020 Ad Aures
* @license https://www.gnu.org/licenses/agpl-3.0.en.html AGPL3
* @link https://castopod.org/
*/
namespace App\Database\Seeds;
use App\Entities\Episode;
use App\Entities\Podcast;
use App\Models\EpisodeModel;
use App\Models\PodcastModel;
use CodeIgniter\Database\Seeder;
use Exception;
use GeoIp2\Database\Reader;
use GeoIp2\Exception\AddressNotFoundException;
use Override;
class FakePodcastsAnalyticsSeeder extends Seeder
{
#[Override]
public function run(): void
{
$jsonUserAgents = json_decode(
......@@ -41,161 +45,162 @@ class FakePodcastsAnalyticsSeeder extends Seeder
$podcast = (new PodcastModel())->first();
if ($podcast !== null) {
$firstEpisode = (new EpisodeModel())
->selectMin('published_at')
->first();
for (
$date = strtotime((string) $firstEpisode->published_at);
$date < strtotime('now');
$date = strtotime(date('Y-m-d', $date) . ' +1 day')
) {
$analyticsPodcasts = [];
$analyticsPodcastsByHour = [];
$analyticsPodcastsByCountry = [];
$analyticsPodcastsByEpisode = [];
$analyticsPodcastsByPlayer = [];
$analyticsPodcastsByRegion = [];
$episodes = (new EpisodeModel())
->where('podcast_id', $podcast->id)
->where('`published_at` <= NOW()', null, false)
->findAll();
foreach ($episodes as $episode) {
$age = floor(($date - strtotime((string) $episode->published_at)) / 86400);
$probability1 = floor(exp(3 - $age / 40)) + 1;
for (
$lineNumber = 0;
$lineNumber < rand(1, (int) $probability1);
++$lineNumber
) {
$probability2 = floor(exp(6 - $age / 20)) + 10;
$player =
$jsonUserAgents[
rand(1, count($jsonUserAgents) - 1)
];
$service =
$jsonRSSUserAgents[
rand(1, count($jsonRSSUserAgents) - 1)
]['slug'];
$app = isset($player['app']) ? $player['app'] : '';
$device = isset($player['device'])
? $player['device']
: '';
$os = isset($player['os']) ? $player['os'] : '';
$isBot = isset($player['bot']) ? $player['bot'] : 0;
$fakeIp =
rand(0, 255) .
'.' .
rand(0, 255) .
'.' .
rand(0, 255) .
'.' .
rand(0, 255);
$cityReader = new Reader(WRITEPATH . 'uploads/GeoLite2-City/GeoLite2-City.mmdb');
$countryCode = 'N/A';
$regionCode = 'N/A';
$latitude = null;
$longitude = null;
try {
$city = $cityReader->city($fakeIp);
$countryCode = $city->country->isoCode === null
? 'N/A'
: $city->country->isoCode;
$regionCode = $city->subdivisions === []
? 'N/A'
: $city->subdivisions[0]->isoCode;
$latitude = round((float) $city->location->latitude, 3);
$longitude = round((float) $city->location->longitude, 3);
} catch (AddressNotFoundException) {
//Bad luck, bad IP, nothing to do.
}
$hits = rand(0, (int) $probability2);
$analyticsPodcasts[] = [
'podcast_id' => $podcast->id,
'date' => date('Y-m-d', $date),
'duration' => rand(60, 3600),
'bandwidth' => rand(1000000, 10000000),
'hits' => $hits,
'unique_listeners' => $hits,
];
$analyticsPodcastsByHour[] = [
'podcast_id' => $podcast->id,
'date' => date('Y-m-d', $date),
'hour' => rand(0, 23),
'hits' => $hits,
];
$analyticsPodcastsByCountry[] = [
'podcast_id' => $podcast->id,
'date' => date('Y-m-d', $date),
'country_code' => $countryCode,
'hits' => $hits,
];
$analyticsPodcastsByEpisode[] = [
'podcast_id' => $podcast->id,
'date' => date('Y-m-d', $date),
'episode_id' => $episode->id,
'age' => $age,
'hits' => $hits,
];
$analyticsPodcastsByPlayer[] = [
'podcast_id' => $podcast->id,
'date' => date('Y-m-d', $date),
'service' => $service,
'app' => $app,
'device' => $device,
'os' => $os,
'is_bot' => $isBot,
'hits' => $hits,
];
$analyticsPodcastsByRegion[] = [
'podcast_id' => $podcast->id,
'date' => date('Y-m-d', $date),
'country_code' => $countryCode,
'region_code' => $regionCode,
'latitude' => $latitude,
'longitude' => $longitude,
'hits' => $hits,
if (! $podcast instanceof Podcast) {
throw new Exception("COULD NOT POPULATE DATABASE:\n\tCreate a podcast with episodes first.\n");
}
$firstEpisode = (new EpisodeModel())
->selectMin('published_at')
->first();
if (! $firstEpisode instanceof Episode) {
throw new Exception("COULD NOT POPULATE DATABASE:\n\tCreate an episode first.");
}
for (
$date = strtotime((string) $firstEpisode->published_at);
$date < strtotime('now');
$date = strtotime(date('Y-m-d', $date) . ' +1 day')
) {
$analyticsPodcasts = [];
$analyticsPodcastsByHour = [];
$analyticsPodcastsByCountry = [];
$analyticsPodcastsByEpisode = [];
$analyticsPodcastsByPlayer = [];
$analyticsPodcastsByRegion = [];
$episodes = (new EpisodeModel())
->where('podcast_id', $podcast->id)
->where('`published_at` <= UTC_TIMESTAMP()', null, false)
->findAll();
foreach ($episodes as $episode) {
$age = floor(($date - strtotime((string) $episode->published_at)) / 86400);
$probability1 = floor(exp(3 - $age / 40)) + 1;
for (
$lineNumber = 0;
$lineNumber < random_int(1, (int) $probability1);
++$lineNumber
) {
$probability2 = floor(exp(6 - $age / 20)) + 10;
$player =
$jsonUserAgents[
random_int(1, count($jsonUserAgents) - 1)
];
$service =
$jsonRSSUserAgents[
random_int(1, count($jsonRSSUserAgents) - 1)
]['slug'];
$app = $player['app'] ?? '';
$device = $player['device'] ?? '';
$os = $player['os'] ?? '';
$isBot = $player['bot'] ?? 0;
$fakeIp =
random_int(0, 255) .
'.' .
random_int(0, 255) .
'.' .
random_int(0, 255) .
'.' .
random_int(0, 255);
$cityReader = new Reader(WRITEPATH . 'uploads/GeoLite2-City/GeoLite2-City.mmdb');
$countryCode = 'N/A';
$regionCode = 'N/A';
$latitude = null;
$longitude = null;
try {
$city = $cityReader->city($fakeIp);
$countryCode = $city->country->isoCode ?? 'N/A';
$regionCode = $city->subdivisions === []
? 'N/A'
: $city->subdivisions[0]->isoCode;
$latitude = round((float) $city->location->latitude, 3);
$longitude = round((float) $city->location->longitude, 3);
} catch (AddressNotFoundException) {
//Bad luck, bad IP, nothing to do.
}
$hits = random_int(0, (int) $probability2);
$analyticsPodcasts[] = [
'podcast_id' => $podcast->id,
'date' => date('Y-m-d', $date),
'duration' => random_int(60, 3600),
'bandwidth' => random_int(1000000, 10000000),
'hits' => $hits,
'unique_listeners' => $hits,
];
$analyticsPodcastsByHour[] = [
'podcast_id' => $podcast->id,
'date' => date('Y-m-d', $date),
'hour' => random_int(0, 23),
'hits' => $hits,
];
$analyticsPodcastsByCountry[] = [
'podcast_id' => $podcast->id,
'date' => date('Y-m-d', $date),
'country_code' => $countryCode,
'hits' => $hits,
];
$analyticsPodcastsByEpisode[] = [
'podcast_id' => $podcast->id,
'date' => date('Y-m-d', $date),
'episode_id' => $episode->id,
'age' => $age,
'hits' => $hits,
];
$analyticsPodcastsByPlayer[] = [
'podcast_id' => $podcast->id,
'date' => date('Y-m-d', $date),
'service' => $service,
'app' => $app,
'device' => $device,
'os' => $os,
'is_bot' => $isBot,
'hits' => $hits,
];
$analyticsPodcastsByRegion[] = [
'podcast_id' => $podcast->id,
'date' => date('Y-m-d', $date),
'country_code' => $countryCode,
'region_code' => $regionCode,
'latitude' => $latitude,
'longitude' => $longitude,
'hits' => $hits,
];
}
$this->db
->table('analytics_podcasts')
->ignore(true)
->insertBatch($analyticsPodcasts);
$this->db
->table('analytics_podcasts_by_hour')
->ignore(true)
->insertBatch($analyticsPodcastsByHour);
$this->db
->table('analytics_podcasts_by_country')
->ignore(true)
->insertBatch($analyticsPodcastsByCountry);
$this->db
->table('analytics_podcasts_by_episode')
->ignore(true)
->insertBatch($analyticsPodcastsByEpisode);
$this->db
->table('analytics_podcasts_by_player')
->ignore(true)
->insertBatch($analyticsPodcastsByPlayer);
$this->db
->table('analytics_podcasts_by_region')
->ignore(true)
->insertBatch($analyticsPodcastsByRegion);
}
} else {
echo "COULD NOT POPULATE DATABASE:\n\tCreate a podcast with episodes first.\n";
$this->db
->table('analytics_podcasts')
->ignore(true)
->insertBatch($analyticsPodcasts);
$this->db
->table('analytics_podcasts_by_hour')
->ignore(true)
->insertBatch($analyticsPodcastsByHour);
$this->db
->table('analytics_podcasts_by_country')
->ignore(true)
->insertBatch($analyticsPodcastsByCountry);
$this->db
->table('analytics_podcasts_by_episode')
->ignore(true)
->insertBatch($analyticsPodcastsByEpisode);
$this->db
->table('analytics_podcasts_by_player')
->ignore(true)
->insertBatch($analyticsPodcastsByPlayer);
$this->db
->table('analytics_podcasts_by_region')
->ignore(true)
->insertBatch($analyticsPodcastsByRegion);
}
}
}
......@@ -5,17 +5,20 @@ declare(strict_types=1);
/**
* Class FakeWebsiteAnalyticsSeeder Inserts Fake Analytics in the database
*
* @copyright 2020 Podlibre
* @copyright 2020 Ad Aures
* @license https://www.gnu.org/licenses/agpl-3.0.en.html AGPL3
* @link https://castopod.org/
*/
namespace App\Database\Seeds;
use App\Entities\Episode;
use App\Entities\Podcast;
use App\Models\EpisodeModel;
use App\Models\PodcastModel;
use CodeIgniter\Database\Seeder;
use Exception;
use Override;
class FakeWebsiteAnalyticsSeeder extends Seeder
{
......@@ -179,90 +182,95 @@ class FakeWebsiteAnalyticsSeeder extends Seeder
'WOSBrowser',
];
#[Override]
public function run(): void
{
$podcast = (new PodcastModel())->first();
if ($podcast) {
$firstEpisode = (new EpisodeModel())
->selectMin('published_at')
->first();
if (! $podcast instanceof Podcast) {
throw new Exception("COULD NOT POPULATE DATABASE:\n\tCreate a podcast with episodes first.\n");
}
for (
$date = strtotime((string) $firstEpisode->published_at);
$date < strtotime('now');
$date = strtotime(date('Y-m-d', $date) . ' +1 day')
) {
$websiteByBrowser = [];
$websiteByEntryPage = [];
$websiteByReferer = [];
$firstEpisode = (new EpisodeModel())
->selectMin('published_at')
->first();
$episodes = (new EpisodeModel())
->where('podcast_id', $podcast->id)
->where('`published_at` <= NOW()', null, false)
->findAll();
foreach ($episodes as $episode) {
$age = floor(($date - strtotime((string) $episode->published_at)) / 86400);
$probability1 = (int) floor(exp(3 - $age / 40)) + 1;
if (! $firstEpisode instanceof Episode) {
throw new Exception("COULD NOT POPULATE DATABASE:\n\tCreate an episode first.");
}
for (
$lineNumber = 0;
$lineNumber < rand(1, $probability1);
++$lineNumber
) {
$probability2 = (int) floor(exp(6 - $age / 20)) + 10;
for (
$date = strtotime((string) $firstEpisode->published_at);
$date < strtotime('now');
$date = strtotime(date('Y-m-d', $date) . ' +1 day')
) {
$websiteByBrowser = [];
$websiteByEntryPage = [];
$websiteByReferer = [];
$domain =
$this->domains[rand(0, count($this->domains) - 1)];
$keyword =
$this->keywords[
rand(0, count($this->keywords) - 1)
];
$browser =
$this->browsers[
rand(0, count($this->browsers) - 1)
];
$episodes = (new EpisodeModel())
->where('podcast_id', $podcast->id)
->where('`published_at` <= UTC_TIMESTAMP()', null, false)
->findAll();
foreach ($episodes as $episode) {
$age = floor(($date - strtotime((string) $episode->published_at)) / 86400);
$probability1 = (int) floor(exp(3 - $age / 40)) + 1;
$hits = rand(0, $probability2);
for (
$lineNumber = 0;
$lineNumber < random_int(1, $probability1);
++$lineNumber
) {
$probability2 = (int) floor(exp(6 - $age / 20)) + 10;
$websiteByBrowser[] = [
'podcast_id' => $podcast->id,
'date' => date('Y-m-d', $date),
'browser' => $browser,
'hits' => $hits,
];
$websiteByEntryPage[] = [
'podcast_id' => $podcast->id,
'date' => date('Y-m-d', $date),
'entry_page_url' => $episode->link,
'hits' => $hits,
$domain =
$this->domains[random_int(0, count($this->domains) - 1)];
$keyword =
$this->keywords[
random_int(0, count($this->keywords) - 1)
];
$websiteByReferer[] = [
'podcast_id' => $podcast->id,
'date' => date('Y-m-d', $date),
'referer_url' =>
'http://' . $domain . '/?q=' . $keyword,
'domain' => $domain,
'keywords' => $keyword,
'hits' => $hits,
$browser =
$this->browsers[
random_int(0, count($this->browsers) - 1)
];
}
$hits = random_int(0, $probability2);
$websiteByBrowser[] = [
'podcast_id' => $podcast->id,
'date' => date('Y-m-d', $date),
'browser' => $browser,
'hits' => $hits,
];
$websiteByEntryPage[] = [
'podcast_id' => $podcast->id,
'date' => date('Y-m-d', $date),
'entry_page_url' => $episode->link,
'hits' => $hits,
];
$websiteByReferer[] = [
'podcast_id' => $podcast->id,
'date' => date('Y-m-d', $date),
'referer_url' => 'http://' . $domain . '/?q=' . $keyword,
'domain' => $domain,
'keywords' => $keyword,
'hits' => $hits,
];
}
$this->db
->table('analytics_website_by_browser')
->ignore(true)
->insertBatch($websiteByBrowser);
$this->db
->table('analytics_website_by_entry_page')
->ignore(true)
->insertBatch($websiteByEntryPage);
$this->db
->table('analytics_website_by_referer')
->ignore(true)
->insertBatch($websiteByReferer);
}
} else {
echo "COULD NOT POPULATE DATABASE:\n\tCreate a podcast with episodes first.\n";
$this->db
->table('analytics_website_by_browser')
->ignore(true)
->insertBatch($websiteByBrowser);
$this->db
->table('analytics_website_by_entry_page')
->ignore(true)
->insertBatch($websiteByEntryPage);
$this->db
->table('analytics_website_by_referer')
->ignore(true)
->insertBatch($websiteByReferer);
}
}
}
......@@ -5,7 +5,7 @@ declare(strict_types=1);
/**
* Class LanguageSeeder Inserts values in languages table in database
*
* @copyright 2020 Podlibre
* @copyright 2020 Ad Aures
* @license https://www.gnu.org/licenses/agpl-3.0.en.html AGPL3
* @link https://castopod.org/
*/
......@@ -18,754 +18,757 @@ declare(strict_types=1);
namespace App\Database\Seeds;
use CodeIgniter\Database\Seeder;
use Override;
class LanguageSeeder extends Seeder
{
#[Override]
public function run(): void
{
$data = [
[
'code' => 'aa',
'code' => 'aa',
'native_name' => 'Afaraf',
],
[
'code' => 'ab',
'code' => 'ab',
'native_name' => 'аҧсуа бызшәа, аҧсшәа',
],
[
'code' => 'ae',
'code' => 'ae',
'native_name' => 'Avesta',
],
[
'code' => 'af',
'code' => 'af',
'native_name' => 'Afrikaans',
],
[
'code' => 'ak',
'code' => 'ak',
'native_name' => 'Akan',
],
[
'code' => 'am',
'code' => 'am',
'native_name' => 'አማርኛ',
],
[
'code' => 'an',
'code' => 'an',
'native_name' => 'Aragonés',
],
[
'code' => 'ar',
'code' => 'ar',
'native_name' => 'العربية',
],
[
'code' => 'as',
'code' => 'as',
'native_name' => 'অসমীয়া',
],
[
'code' => 'av',
'code' => 'av',
'native_name' => 'авар мацӀ, магӀарул мацӀ',
],
[
'code' => 'ay',
'code' => 'ay',
'native_name' => 'Aymar aru',
],
[
'code' => 'az',
'code' => 'az',
'native_name' => 'azərbaycan dili',
],
[
'code' => 'ba',
'code' => 'ba',
'native_name' => 'башҡорт теле',
],
[
'code' => 'be',
'code' => 'be',
'native_name' => 'беларуская мова',
],
[
'code' => 'bg',
'code' => 'bg',
'native_name' => 'български език',
],
[
'code' => 'bh',
'code' => 'bh',
'native_name' => 'भोजपुरी',
],
[
'code' => 'bi',
'code' => 'bi',
'native_name' => 'Bislama',
],
[
'code' => 'bm',
'code' => 'bm',
'native_name' => 'Bamanankan',
],
[
'code' => 'bn',
'code' => 'bn',
'native_name' => 'বাংলা',
],
[
'code' => 'bo',
'code' => 'bo',
'native_name' => 'བོད་ཡིག',
],
[
'code' => 'br',
'code' => 'br',
'native_name' => 'Brezhoneg',
],
[
'code' => 'bs',
'code' => 'bs',
'native_name' => 'Bosanski jezik',
],
[
'code' => 'ca',
'code' => 'ca',
'native_name' => 'Català, valencià',
],
[
'code' => 'ce',
'code' => 'ce',
'native_name' => 'нохчийн мотт',
],
[
'code' => 'ch',
'code' => 'ch',
'native_name' => 'Chamoru',
],
[
'code' => 'co',
'code' => 'co',
'native_name' => 'Corsu, lingua corsa',
],
[
'code' => 'cr',
'code' => 'cr',
'native_name' => 'ᓀᐦᐃᔭᐍᐏᐣ',
],
[
'code' => 'cs',
'code' => 'cs',
'native_name' => 'čeština, český jazyk',
],
[
'code' => 'cu',
'code' => 'cu',
'native_name' => 'ѩзыкъ словѣньскъ',
],
[
'code' => 'cv',
'code' => 'cv',
'native_name' => 'чӑваш чӗлхи',
],
[
'code' => 'cy',
'code' => 'cy',
'native_name' => 'Cymraeg',
],
[
'code' => 'da',
'code' => 'da',
'native_name' => 'Dansk',
],
[
'code' => 'de',
'code' => 'de',
'native_name' => 'Deutsch',
],
[
'code' => 'dv',
'code' => 'dv',
'native_name' => 'ދިވެހި',
],
[
'code' => 'dz',
'code' => 'dz',
'native_name' => 'རྫོང་ཁ',
],
[
'code' => 'ee',
'code' => 'ee',
'native_name' => 'Eʋegbe',
],
[
'code' => 'el',
'code' => 'el',
'native_name' => 'ελληνικά',
],
[
'code' => 'en',
'code' => 'en',
'native_name' => 'English',
],
[
'code' => 'eo',
'code' => 'eo',
'native_name' => 'Esperanto',
],
[
'code' => 'es',
'code' => 'es',
'native_name' => 'Español',
],
[
'code' => 'et',
'code' => 'et',
'native_name' => 'eesti, eesti keel',
],
[
'code' => 'eu',
'code' => 'eu',
'native_name' => 'Euskara, euskera',
],
[
'code' => 'fa',
'code' => 'fa',
'native_name' => 'فارسی',
],
[
'code' => 'ff',
'code' => 'ff',
'native_name' => 'Fulfulde, Pulaar, Pular',
],
[
'code' => 'fi',
'code' => 'fi',
'native_name' => 'Suomi, suomen kieli',
],
[
'code' => 'fj',
'code' => 'fj',
'native_name' => 'Vosa Vakaviti',
],
[
'code' => 'fo',
'code' => 'fo',
'native_name' => 'Føroyskt',
],
[
'code' => 'fr',
'code' => 'fr',
'native_name' => 'Français, langue française',
],
[
'code' => 'fy',
'code' => 'fy',
'native_name' => 'Frysk',
],
[
'code' => 'ga',
'code' => 'ga',
'native_name' => 'Gaeilge',
],
[
'code' => 'gd',
'code' => 'gd',
'native_name' => 'Gàidhlig',
],
[
'code' => 'gl',
'code' => 'gl',
'native_name' => 'Galego',
],
[
'code' => 'gn',
'code' => 'gn',
'native_name' => "Avañe'ẽ",
],
[
'code' => 'gu',
'code' => 'gu',
'native_name' => 'ગુજરાતી',
],
[
'code' => 'gv',
'code' => 'gv',
'native_name' => 'Gaelg, Gailck',
],
[
'code' => 'ha',
'code' => 'ha',
'native_name' => '(Hausa) هَوُسَ',
],
[
'code' => 'he',
'code' => 'he',
'native_name' => 'עברית',
],
[
'code' => 'hi',
'code' => 'hi',
'native_name' => 'हिन्दी, हिंदी',
],
[
'code' => 'ho',
'code' => 'ho',
'native_name' => 'Hiri Motu',
],
[
'code' => 'hr',
'code' => 'hr',
'native_name' => 'Hrvatski jezik',
],
[
'code' => 'ht',
'code' => 'ht',
'native_name' => 'Kreyòl ayisyen',
],
[
'code' => 'hu',
'code' => 'hu',
'native_name' => 'Magyar',
],
[
'code' => 'hy',
'code' => 'hy',
'native_name' => 'Հայերեն',
],
[
'code' => 'hz',
'code' => 'hz',
'native_name' => 'Otjiherero',
],
[
'code' => 'ia',
'code' => 'ia',
'native_name' => 'Interlingua',
],
[
'code' => 'id',
'code' => 'id',
'native_name' => 'Bahasa Indonesia',
],
[
'code' => 'ie',
'native_name' =>
'Interlingue, formerly Occidental',
'code' => 'ie',
'native_name' => 'Interlingue, formerly Occidental',
],
[
'code' => 'ig',
'code' => 'ig',
'native_name' => 'Asụsụ Igbo',
],
[
'code' => 'ii',
'code' => 'ii',
'native_name' => 'ꆈꌠ꒿ Nuosuhxop',
],
[
'code' => 'ik',
'code' => 'ik',
'native_name' => 'Iñupiaq, Iñupiatun',
],
[
'code' => 'io',
'code' => 'io',
'native_name' => 'Ido',
],
[
'code' => 'is',
'code' => 'is',
'native_name' => 'Íslenska',
],
[
'code' => 'it',
'code' => 'it',
'native_name' => 'Italiano',
],
[
'code' => 'iu',
'code' => 'iu',
'native_name' => 'ᐃᓄᒃᑎᑐᑦ',
],
[
'code' => 'ja',
'code' => 'ja',
'native_name' => '日本語 (にほんご)',
],
[
'code' => 'jv',
'code' => 'jv',
'native_name' => 'ꦧꦱꦗꦮ, Basa Jawa',
],
[
'code' => 'ka',
'code' => 'ka',
'native_name' => 'ქართული',
],
[
'code' => 'kg',
'code' => 'kg',
'native_name' => 'Kikongo',
],
[
'code' => 'ki',
'code' => 'ki',
'native_name' => 'Gĩkũyũ',
],
[
'code' => 'kj',
'code' => 'kj',
'native_name' => 'Kuanyama',
],
[
'code' => 'kk',
'code' => 'kk',
'native_name' => 'қазақ тілі',
],
[
'code' => 'kl',
'code' => 'kl',
'native_name' => 'Kalaallisut, kalaallit oqaasii',
],
[
'code' => 'km',
'code' => 'km',
'native_name' => 'ខ្មែរ, ខេមរភាសា, ភាសាខ្មែរ',
],
[
'code' => 'kn',
'code' => 'kn',
'native_name' => 'ಕನ್ನಡ',
],
[
'code' => 'ko',
'code' => 'ko',
'native_name' => '한국어',
],
[
'code' => 'kr',
'code' => 'kr',
'native_name' => 'Kanuri',
],
[
'code' => 'ks',
'code' => 'ks',
'native_name' => 'कश्मीरी, كشميري',
],
[
'code' => 'ku',
'code' => 'ku',
'native_name' => 'Kurdî, کوردی',
],
[
'code' => 'kv',
'code' => 'kv',
'native_name' => 'коми кыв',
],
[
'code' => 'kw',
'code' => 'kw',
'native_name' => 'Kernewek',
],
[
'code' => 'ky',
'code' => 'ky',
'native_name' => 'Кыргызча, Кыргыз тили',
],
[
'code' => 'la',
'code' => 'la',
'native_name' => 'Latine, lingua latina',
],
[
'code' => 'lb',
'code' => 'lb',
'native_name' => 'Lëtzebuergesch',
],
[
'code' => 'lg',
'code' => 'lg',
'native_name' => 'Luganda',
],
[
'code' => 'li',
'code' => 'li',
'native_name' => 'Limburgs',
],
[
'code' => 'ln',
'code' => 'ln',
'native_name' => 'Lingála',
],
[
'code' => 'lo',
'code' => 'lo',
'native_name' => 'ພາສາລາວ',
],
[
'code' => 'lt',
'code' => 'lt',
'native_name' => 'Lietuvių kalba',
],
[
'code' => 'lu',
'code' => 'lu',
'native_name' => 'Kiluba',
],
[
'code' => 'lv',
'code' => 'lv',
'native_name' => 'Latviešu valoda',
],
[
'code' => 'mg',
'code' => 'mg',
'native_name' => 'Fiteny malagasy',
],
[
'code' => 'mh',
'code' => 'mh',
'native_name' => 'Kajin M̧ajeļ',
],
[
'code' => 'mi',
'code' => 'mi',
'native_name' => 'Te reo Māori',
],
[
'code' => 'mk',
'code' => 'mk',
'native_name' => 'македонски јазик',
],
[
'code' => 'ml',
'code' => 'ml',
'native_name' => 'മലയാളം',
],
[
'code' => 'mn',
'code' => 'mn',
'native_name' => 'Монгол хэл',
],
[
'code' => 'mr',
'code' => 'mr',
'native_name' => 'मराठी',
],
[
'code' => 'ms',
'code' => 'ms',
'native_name' => 'Bahasa Melayu, بهاس ملايو',
],
[
'code' => 'mt',
'code' => 'mt',
'native_name' => 'Malti',
],
[
'code' => 'my',
'code' => 'my',
'native_name' => 'ဗမာစာ',
],
[
'code' => 'na',
'code' => 'na',
'native_name' => 'Dorerin Naoero',
],
[
'code' => 'nb',
'code' => 'nb',
'native_name' => 'Norsk Bokmål',
],
[
'code' => 'nd',
'code' => 'nd',
'native_name' => 'isiNdebele',
],
[
'code' => 'ne',
'code' => 'ne',
'native_name' => 'नेपाली',
],
[
'code' => 'ng',
'code' => 'ng',
'native_name' => 'Owambo',
],
[
'code' => 'nl',
'code' => 'nl',
'native_name' => 'Nederlands, Vlaams',
],
[
'code' => 'nn',
'code' => 'nn',
'native_name' => 'Norsk Nynorsk',
],
[
'code' => 'no',
'code' => 'no',
'native_name' => 'Norsk',
],
[
'code' => 'nr',
'code' => 'nr',
'native_name' => 'isiNdebele',
],
[
'code' => 'nv',
'code' => 'nv',
'native_name' => 'Diné bizaad',
],
[
'code' => 'ny',
'code' => 'ny',
'native_name' => 'Chicheŵa, chinyanja',
],
[
'code' => 'oc',
'code' => 'oc',
'native_name' => 'Occitan, lenga d’òc',
],
[
'code' => 'oj',
'code' => 'oj',
'native_name' => 'ᐊᓂᔑᓈᐯᒧᐎᓐ',
],
[
'code' => 'om',
'code' => 'om',
'native_name' => 'Afaan Oromoo',
],
[
'code' => 'or',
'code' => 'or',
'native_name' => 'ଓଡ଼ିଆ',
],
[
'code' => 'os',
'code' => 'os',
'native_name' => 'ирон æвзаг',
],
[
'code' => 'pa',
'code' => 'pa',
'native_name' => 'ਪੰਜਾਬੀ, پنجابی',
],
[
'code' => 'pi',
'code' => 'pi',
'native_name' => 'पालि, पाळि',
],
[
'code' => 'pl',
'code' => 'pl',
'native_name' => 'język polski, polszczyzna',
],
[
'code' => 'ps',
'code' => 'ps',
'native_name' => 'پښتو',
],
[
'code' => 'pt',
'code' => 'pt',
'native_name' => 'Português',
],
[
'code' => 'qu',
'code' => 'qu',
'native_name' => 'Runa Simi, Kichwa',
],
[
'code' => 'rm',
'code' => 'rm',
'native_name' => 'Rumantsch Grischun',
],
[
'code' => 'rn',
'code' => 'rn',
'native_name' => 'Ikirundi',
],
[
'code' => 'ro',
'code' => 'ro',
'native_name' => 'Română',
],
[
'code' => 'ru',
'code' => 'ru',
'native_name' => 'Pусский',
],
[
'code' => 'rw',
'code' => 'rw',
'native_name' => 'Ikinyarwanda',
],
[
'code' => 'sa',
'code' => 'sa',
'native_name' => 'संस्कृतम्',
],
[
'code' => 'sc',
'code' => 'sc',
'native_name' => 'Sardu',
],
[
'code' => 'sd',
'code' => 'sd',
'native_name' => 'सिन्धी, سنڌي، سندھی',
],
[
'code' => 'se',
'code' => 'se',
'native_name' => 'Davvisámegiella',
],
[
'code' => 'sg',
'code' => 'sg',
'native_name' => 'Yângâ tî sängö',
],
[
'code' => 'si',
'code' => 'si',
'native_name' => 'සිංහල',
],
[
'code' => 'sk',
'code' => 'sk',
'native_name' => 'Slovenčina, Slovenský Jazyk',
],
[
'code' => 'sl',
'code' => 'sl',
'native_name' => 'Slovenski Jezik, Slovenščina',
],
[
'code' => 'sm',
'code' => 'sm',
'native_name' => "Gagana fa'a Samoa",
],
[
'code' => 'sn',
'code' => 'sn',
'native_name' => 'chiShona',
],
[
'code' => 'so',
'code' => 'so',
'native_name' => 'Soomaaliga, af Soomaali',
],
[
'code' => 'sq',
'code' => 'sq',
'native_name' => 'Shqip',
],
[
'code' => 'sr',
'code' => 'sr',
'native_name' => 'српски језик',
],
[
'code' => 'ss',
'code' => 'ss',
'native_name' => 'SiSwati',
],
[
'code' => 'st',
'code' => 'st',
'native_name' => 'Sesotho',
],
[
'code' => 'su',
'code' => 'su',
'native_name' => 'Basa Sunda',
],
[
'code' => 'sv',
'code' => 'sv',
'native_name' => 'Svenska',
],
[
'code' => 'sw',
'code' => 'sw',
'native_name' => 'Kiswahili',
],
[
'code' => 'ta',
'code' => 'ta',
'native_name' => 'தமிழ்',
],
[
'code' => 'te',
'code' => 'te',
'native_name' => 'తెలుగు',
],
[
'code' => 'tg',
'code' => 'tg',
'native_name' => 'тоҷикӣ, toçikī, تاجیکی',
],
[
'code' => 'th',
'code' => 'th',
'native_name' => 'ไทย',
],
[
'code' => 'ti',
'code' => 'ti',
'native_name' => 'ትግርኛ',
],
[
'code' => 'tk',
'code' => 'tk',
'native_name' => 'Türkmen, Түркмен',
],
[
'code' => 'tl',
'code' => 'tl',
'native_name' => 'Wikang Tagalog',
],
[
'code' => 'tn',
'code' => 'tn',
'native_name' => 'Setswana',
],
[
'code' => 'to',
'code' => 'to',
'native_name' => 'Faka Tonga',
],
[
'code' => 'tr',
'code' => 'tr',
'native_name' => 'Türkçe',
],
[
'code' => 'ts',
'code' => 'ts',
'native_name' => 'Xitsonga',
],
[
'code' => 'tt',
'code' => 'tt',
'native_name' => 'татар теле, tatar tele',
],
[
'code' => 'tw',
'code' => 'tw',
'native_name' => 'Twi',
],
[
'code' => 'ty',
'code' => 'ty',
'native_name' => 'Reo Tahiti',
],
[
'code' => 'ug',
'code' => 'ug',
'native_name' => 'ئۇيغۇرچە, Uyghurche',
],
[
'code' => 'uk',
'code' => 'uk',
'native_name' => 'Українська',
],
[
'code' => 'ur',
'code' => 'ur',
'native_name' => 'اردو',
],
[
'code' => 'uz',
'code' => 'uz',
'native_name' => 'Oʻzbek, Ўзбек, أۇزبېك',
],
[
'code' => 've',
'code' => 've',
'native_name' => 'Tshivenḓa',
],
[
'code' => 'vi',
'code' => 'vi',
'native_name' => 'Tiếng Việt',
],
[
'code' => 'vo',
'code' => 'vo',
'native_name' => 'Volapük',
],
[
'code' => 'wa',
'code' => 'wa',
'native_name' => 'Walon',
],
[
'code' => 'wo',
'code' => 'wo',
'native_name' => 'Wollof',
],
[
'code' => 'xh',
'code' => 'xh',
'native_name' => 'isiXhosa',
],
[
'code' => 'yi',
'code' => 'yi',
'native_name' => 'ייִדיש',
],
[
'code' => 'yo',
'code' => 'yo',
'native_name' => 'Yorùbá',
],
[
'code' => 'za',
'code' => 'za',
'native_name' => 'Saɯ cueŋƅ, Saw cuengh',
],
[
'code' => 'zh',
'code' => 'zh',
'native_name' => '中文 (Zhōngwén), 汉语, 漢語',
],
[
'code' => 'zu',
'code' => 'zu',
'native_name' => 'isiZulu',
],
];
$this->db
->table('languages')
->ignore(true)
->insertBatch($data);
foreach ($data as $languageLine) {
$this->db
->table('languages')
->ignore(true)
->insert($languageLine);
}
}
}
<?php
declare(strict_types=1);
/**
* Class PlatformsSeeder Inserts values in platforms table in database
*
* @copyright 2020 Podlibre
* @license https://www.gnu.org/licenses/agpl-3.0.en.html AGPL3
* @link https://castopod.org/
*/
namespace App\Database\Seeds;
use CodeIgniter\Database\Seeder;
class PlatformSeeder extends Seeder
{
public function run(): void
{
$data = [
[
'slug' => 'amazon',
'type' => 'podcasting',
'label' => 'Amazon Music and Audible',
'home_url' => 'https://music.amazon.com/podcasts',
'submit_url' => 'http://amazon.com/podcasters',
],
[
'slug' => 'antennapod',
'type' => 'podcasting',
'label' => 'AntennaPod',
'home_url' => 'https://antennapod.org/',
'submit_url' => 'https://api.podcastindex.org/signup',
],
[
'slug' => 'apple',
'type' => 'podcasting',
'label' => 'Apple Podcasts',
'home_url' => 'https://www.apple.com/itunes/podcasts/',
'submit_url' =>
'https://podcastsconnect.apple.com/my-podcasts/new-feed',
],
[
'slug' => 'blubrry',
'type' => 'podcasting',
'label' => 'Blubrry',
'home_url' => 'https://www.blubrry.com/',
'submit_url' => 'https://www.blubrry.com/addpodcast.php',
],
[
'slug' => 'breaker',
'type' => 'podcasting',
'label' => 'Breaker',
'home_url' => 'https://www.breaker.audio/',
'submit_url' => 'https://podcasters.breaker.audio/',
],
[
'slug' => 'castbox',
'type' => 'podcasting',
'label' => 'Castbox',
'home_url' => 'https://castbox.fm/',
'submit_url' =>
'https://helpcenter.castbox.fm/portal/kb/articles/submit-my-podcast',
],
[
'slug' => 'castopod',
'type' => 'podcasting',
'label' => 'Castopod',
'home_url' => 'https://castopod.org/',
'submit_url' => 'https://castopod.org/instances',
],
[
'slug' => 'castro',
'type' => 'podcasting',
'label' => 'Castro',
'home_url' => 'http://castro.fm/',
'submit_url' =>
'https://castro.fm/support/link-to-your-podcast-in-castro',
],
[
'slug' => 'chartable',
'type' => 'podcasting',
'label' => 'Chartable',
'home_url' => 'https://chartable.com/',
'submit_url' => 'https://chartable.com/podcasts/submit',
],
[
'slug' => 'deezer',
'type' => 'podcasting',
'label' => 'Deezer',
'home_url' => 'https://www.deezer.com/',
'submit_url' => 'https://podcasters.deezer.com/submission',
],
[
'slug' => 'fyyd',
'type' => 'podcasting',
'label' => 'fyyd',
'home_url' => 'https://fyyd.de/',
'submit_url' => 'https://fyyd.de/add-feed',
],
[
'slug' => 'google',
'type' => 'podcasting',
'label' => 'Google Podcasts',
'home_url' => 'https://podcasts.google.com/about',
'submit_url' =>
'https://search.google.com/search-console/about',
],
[
'slug' => 'ivoox',
'type' => 'podcasting',
'label' => 'Ivoox',
'home_url' => 'https://www.ivoox.com/',
'submit_url' => 'http://www.ivoox.com/upload-podcast_u.html',
],
[
'slug' => 'listennotes',
'type' => 'podcasting',
'label' => 'ListenNotes',
'home_url' => 'https://www.listennotes.com/',
'submit_url' => 'https://www.listennotes.com/submit/',
],
[
'slug' => 'overcast',
'type' => 'podcasting',
'label' => 'Overcast',
'home_url' => 'https://overcast.fm/',
'submit_url' => 'https://overcast.fm/podcasterinfo',
],
[
'slug' => 'playerfm',
'type' => 'podcasting',
'label' => 'Player.Fm',
'home_url' => 'https://player.fm/',
'submit_url' => 'https://player.fm/importer/feed',
],
[
'slug' => 'pocketcasts',
'type' => 'podcasting',
'label' => 'Pocketcasts',
'home_url' => 'https://www.pocketcasts.com/',
'submit_url' => 'https://www.pocketcasts.com/submit/',
],
[
'slug' => 'podbean',
'type' => 'podcasting',
'label' => 'Podbean',
'home_url' => 'https://www.podbean.com/',
'submit_url' => 'https://www.podbean.com/site/submitPodcast',
],
[
'slug' => 'podcastaddict',
'type' => 'podcasting',
'label' => 'Podcast Addict',
'home_url' => 'https://podcastaddict.com/',
'submit_url' => 'https://podcastaddict.com/submit',
],
[
'slug' => 'podcastindex',
'type' => 'podcasting',
'label' => 'Podcast Index',
'home_url' => 'https://podcastindex.org/',
'submit_url' => 'https://api.podcastindex.org/signup',
],
[
'slug' => 'podchaser',
'type' => 'podcasting',
'label' => 'Podchaser',
'home_url' => 'https://www.podchaser.com/',
'submit_url' => 'https://www.podchaser.com/creators/edit',
],
[
'slug' => 'podcloud',
'type' => 'podcasting',
'label' => 'podCloud',
'home_url' => 'https://podcloud.fr/',
'submit_url' => 'https://podcloud.fr/studio/podcasts/new',
],
[
'slug' => 'podinstall',
'type' => 'podcasting',
'label' => 'Podinstall',
'home_url' => 'https://www.podinstall.com/',
'submit_url' => 'https://www.podinstall.com/claim.html',
],
[
'slug' => 'podlink',
'type' => 'podcasting',
'label' => 'pod.link',
'home_url' => 'https://pod.link/',
'submit_url' => 'https://pod.link',
],
[
'slug' => 'podtail',
'type' => 'podcasting',
'label' => 'Podtail',
'home_url' => 'https://podtail.com/',
'submit_url' => 'https://podtail.com/about/faq/',
],
[
'slug' => 'podfriend',
'type' => 'podcasting',
'label' => 'Podfriend',
'home_url' => 'https://www.podfriend.com/',
'submit_url' => 'https://api.podcastindex.org/signup',
],
[
'slug' => 'podverse',
'type' => 'podcasting',
'label' => 'Podverse',
'home_url' => 'https://podverse.fm/',
'submit_url' =>
'https://docs.google.com/forms/d/e/1FAIpQLSdewKP-YrE8zGjDPrkmoJEwCxPl_gizEkmzAlTYsiWAuAk1Ng/viewform',
],
[
'slug' => 'radiopublic',
'type' => 'podcasting',
'label' => 'RadioPublic',
'home_url' => 'https://radiopublic.com/',
'submit_url' => 'https://podcasters.radiopublic.com/signup',
],
[
'slug' => 'spotify',
'type' => 'podcasting',
'label' => 'Spotify',
'home_url' => 'https://www.spotify.com/',
'submit_url' => 'https://podcasters.spotify.com/submit',
],
[
'slug' => 'spreaker',
'type' => 'podcasting',
'label' => 'Spreaker',
'home_url' => 'https://www.spreaker.com/',
'submit_url' => 'https://www.spreaker.com/cms/shows/rss-import',
],
[
'slug' => 'stitcher',
'type' => 'podcasting',
'label' => 'Stitcher',
'home_url' => 'https://www.stitcher.com/',
'submit_url' => 'https://partners.stitcher.com/join',
],
[
'slug' => 'tunein',
'type' => 'podcasting',
'label' => 'TuneIn',
'home_url' => 'https://tunein.com/',
'submit_url' =>
'https://help.tunein.com/contact/add-podcast-S19TR3Sdf',
],
[
'slug' => 'anytime',
'type' => 'podcasting',
'label' => 'Anytime Podcast Player',
'home_url' => 'https://anytimeplayer.app/',
'submit_url' => '',
],
[
'slug' => 'breez',
'type' => 'podcasting',
'label' => 'Breez',
'home_url' => 'https://breez.technology/',
'submit_url' => '',
],
[
'slug' => 'castamatic',
'type' => 'podcasting',
'label' => 'Castamatic',
'home_url' => 'https://castamatic.com/',
'submit_url' => '',
],
[
'slug' => 'castcoverage',
'type' => 'podcasting',
'label' => 'CastCoverage',
'home_url' => 'http://castcoverage.com/',
'submit_url' => '',
],
[
'slug' => 'curiocaster',
'type' => 'podcasting',
'label' => 'CurioCaster',
'home_url' => 'https://curiocaster.com/',
'submit_url' => '',
],
[
'slug' => 'escapepod',
'type' => 'podcasting',
'label' => 'Escapepod',
'home_url' => 'http://y20k.org/escapepod/',
'submit_url' => '',
],
[
'slug' => 'fountain',
'type' => 'podcasting',
'label' => 'Fountain',
'home_url' => 'https://www.fountain.fm/',
'submit_url' => '',
],
[
'slug' => 'gpodder',
'type' => 'podcasting',
'label' => 'gPodder',
'home_url' => 'https://gpodder.org/',
'submit_url' => '',
],
[
'slug' => 'hypercatcher',
'type' => 'podcasting',
'label' => 'HyperCatcher',
'home_url' => 'https://hypercatcher.com/',
'submit_url' => '',
],
[
'slug' => 'ivyfm',
'type' => 'podcasting',
'label' => 'Ivy Podcast Discovery',
'home_url' => 'https://ivy.fm/',
'submit_url' => '',
],
[
'slug' => 'jumplink',
'type' => 'podcasting',
'label' => 'JumpLink',
'home_url' => 'https://jump.link/',
'submit_url' => 'https://jump.link/a/accounts/signup/',
],
[
'slug' => 'kasts',
'type' => 'podcasting',
'label' => 'Kasts',
'home_url' => 'https://apps.kde.org/kasts/',
'submit_url' => '',
],
[
'slug' => 'playapod',
'type' => 'podcasting',
'label' => 'Playapod',
'home_url' => 'https://playapod.com/',
'submit_url' => '',
],
[
'slug' => 'plink',
'type' => 'podcasting',
'label' => 'Plink',
'home_url' => 'https://plinkhq.com/',
'submit_url' => '',
],
[
'slug' => 'podcastchapters',
'type' => 'podcasting',
'label' => 'Podcast Chapters',
'home_url' => 'https://chaptersapp.com/',
'submit_url' => '',
],
[
'slug' => 'podcastguru',
'type' => 'podcasting',
'label' => 'Podcast Guru',
'home_url' => 'https://podcastguru.io/',
'submit_url' => 'https://podcastguru.io/promote-your-podcast/',
],
[
'slug' => 'podlp',
'type' => 'podcasting',
'label' => 'PodLP',
'home_url' => 'https://podlp.com/',
'submit_url' => 'https://podlp.com/submit.html',
],
[
'slug' => 'podnews',
'type' => 'podcasting',
'label' => 'podnews',
'home_url' => 'https://podnews.net/podcast/subscribe-pages',
'submit_url' => '',
],
[
'slug' => 'podstation',
'type' => 'podcasting',
'label' => 'podStation',
'home_url' => 'https://podstation.github.io/',
'submit_url' => '',
],
[
'slug' => 'sphinxchat',
'type' => 'podcasting',
'label' => 'Sphinx',
'home_url' => 'https://sphinx.chat/',
'submit_url' => '',
],
[
'slug' => 'tsacdop',
'type' => 'podcasting',
'label' => 'Tsacdop',
'home_url' => 'https://www.tsacdop.app/',
'submit_url' => '',
],
[
'slug' => 'zion',
'type' => 'podcasting',
'label' => 'Zion',
'home_url' => 'https://getzion.com/',
'submit_url' => 'https://shop.n2n2.chat/',
],
[
'slug' => 'paypal',
'type' => 'funding',
'label' => 'Paypal',
'home_url' => 'https://www.paypal.com/',
'submit_url' => 'https://www.paypal.com/paypalme/my/grab',
],
[
'slug' => 'gofundme',
'type' => 'funding',
'label' => 'GoFundMe',
'home_url' => 'https://www.gofundme.com/',
'submit_url' => 'https://www.gofundme.com/sign-up',
],
[
'slug' => 'helloasso',
'type' => 'funding',
'label' => 'helloasso',
'home_url' => 'https://www.helloasso.com/',
'submit_url' => 'https://auth.helloasso.com/inscription',
],
[
'slug' => 'indiegogo',
'type' => 'funding',
'label' => 'Indiegogo',
'home_url' => 'https://www.indiegogo.com/',
'submit_url' => 'https://www.indiegogo.com/start-a-campaign#/',
],
[
'slug' => 'kickstarter',
'type' => 'funding',
'label' => 'Kickstarter',
'home_url' => 'https://www.kickstarter.com/',
'submit_url' => 'https://www.kickstarter.com/learn',
],
[
'slug' => 'kisskissbankbank',
'type' => 'funding',
'label' => 'KissKissBankBank',
'home_url' => 'https://www.kisskissbankbank.com/',
'submit_url' =>
'https://www.kisskissbankbank.com/en/financer-mon-projet',
],
[
'slug' => 'liberapay',
'type' => 'funding',
'label' => 'Liberapay',
'home_url' => 'https://liberapay.com/',
'submit_url' => 'https://liberapay.com/sign-up',
],
[
'slug' => 'patreon',
'type' => 'funding',
'label' => 'Patreon',
'home_url' => 'https://www.patreon.com/',
'submit_url' => 'https://www.patreon.com/create',
],
[
'slug' => 'tipeee',
'type' => 'funding',
'label' => 'Tipeee',
'home_url' => 'https://tipeee.com/',
'submit_url' => 'https://tipeee.com/register/',
],
[
'slug' => 'ulule',
'type' => 'funding',
'label' => 'Ulule',
'home_url' => 'https://www.ulule.com/',
'submit_url' => 'https://www.ulule.com/projects/create/#/',
],
[
'slug' => 'discord',
'type' => 'social',
'label' => 'Discord',
'home_url' => 'https://discord.com/',
'submit_url' => 'https://discord.com/register',
],
[
'slug' => 'facebook',
'type' => 'social',
'label' => 'Facebook',
'home_url' => 'https://www.facebook.com/',
'submit_url' =>
'https://www.facebook.com/pages/creation/?ref_type=comet_home',
],
[
'slug' => 'funkwhale',
'type' => 'social',
'label' => 'Funkwhale',
'home_url' => 'https://funkwhale.audio/',
'submit_url' => 'https://network.funkwhale.audio/dashboards/',
],
[
'slug' => 'instagram',
'type' => 'social',
'label' => 'Instagram',
'home_url' => 'https://www.instagram.com/',
'submit_url' =>
'https://www.instagram.com/accounts/emailsignup/',
],
[
'slug' => 'linkedin',
'type' => 'social',
'label' => 'LinkedIn',
'home_url' => 'https://www.linkedin.com/',
'submit_url' => 'https://www.linkedin.com/company/setup/new/',
],
[
'slug' => 'mastodon',
'type' => 'social',
'label' => 'Mastodon',
'home_url' => 'https://joinmastodon.org/',
'submit_url' => 'https://joinmastodon.org/communities',
],
[
'slug' => 'mobilizon',
'type' => 'social',
'label' => 'Mobilizon',
'home_url' => 'https://joinmobilizon.org/',
'submit_url' => 'https://instances.joinmobilizon.org/instances',
],
[
'slug' => 'peertube',
'type' => 'social',
'label' => 'PeerTube',
'home_url' => 'https://joinpeertube.org/',
'submit_url' => 'https://joinpeertube.org/instances',
],
[
'slug' => 'pixelfed',
'type' => 'social',
'label' => 'Pixelfed',
'home_url' => 'https://pixelfed.org/',
'submit_url' => 'https://beta.joinpixelfed.org/',
],
[
'slug' => 'plume',
'type' => 'social',
'label' => 'Plume',
'home_url' => 'https://joinplu.me/',
'submit_url' => 'https://joinplu.me/#instances',
],
[
'slug' => 'slack',
'type' => 'social',
'label' => 'Slack',
'home_url' => 'https://slack.com/',
'submit_url' => 'https://slack.com/get-started#/create',
],
[
'slug' => 'twitch',
'type' => 'social',
'label' => 'Twitch',
'home_url' => 'https://www.twitch.tv/',
'submit_url' => 'https://www.twitch.tv/signup',
],
[
'slug' => 'twitter',
'type' => 'social',
'label' => 'Twitter',
'home_url' => 'https://twitter.com/',
'submit_url' => 'https://twitter.com/i/flow/signup',
],
[
'slug' => 'writefreely',
'type' => 'social',
'label' => 'WriteFreely',
'home_url' => 'https://writefreely.org/',
'submit_url' => 'https://writefreely.org/instances',
],
[
'slug' => 'youtube',
'type' => 'social',
'label' => 'Youtube',
'home_url' => 'https://www.youtube.com/',
'submit_url' => 'https://creatoracademy.youtube.com/page/home',
],
];
$this->db
->table('platforms')
->ignore(true)
->insertBatch($data);
}
}
<?php
declare(strict_types=1);
/**
* Class TestSeeder Inserts a superadmin user in the database
*
* @copyright 2020 Podlibre
* @license https://www.gnu.org/licenses/agpl-3.0.en.html AGPL3
* @link https://castopod.org/
*/
namespace App\Database\Seeds;
use CodeIgniter\Database\Seeder;
class TestSeeder extends Seeder
{
public function run(): void
{
/**
* Inserts an active user with the following credentials: username: admin password: AGUehL3P
*/
$this->db->table('users')
->insert([
'id' => 1,
'username' => 'admin',
'email' => 'admin@example.com',
'password_hash' =>
'$2y$10$TXJEHX/djW8jtzgpDVf7dOOCGo5rv1uqtAYWdwwwkttQcDkAeB2.6',
'active' => 1,
]);
$this->db
->table('auth_groups_users')
->insert([
'group_id' => 1,
'user_id' => 1,
]);
}
}
......@@ -3,22 +3,23 @@
declare(strict_types=1);
/**
* @copyright 2020 Podlibre
* @copyright 2020 Ad Aures
* @license https://www.gnu.org/licenses/agpl-3.0.en.html AGPL3
* @link https://castopod.org/
*/
namespace App\Entities;
use ActivityPub\Entities\Actor as ActivityPubActor;
use App\Models\PodcastModel;
use Modules\Fediverse\Entities\Actor as FediverseActor;
use Override;
use RuntimeException;
/**
* @property Podcast|null $podcast
* @property boolean $is_podcast
*/
class Actor extends ActivityPubActor
class Actor extends FediverseActor
{
protected ?Podcast $podcast = null;
......@@ -26,7 +27,7 @@ class Actor extends ActivityPubActor
public function getIsPodcast(): bool
{
return $this->getPodcast() !== null;
return $this->getPodcast() instanceof Podcast;
}
public function getPodcast(): ?Podcast
......@@ -35,10 +36,30 @@ class Actor extends ActivityPubActor
throw new RuntimeException('Podcast id must be set before getting associated podcast.');
}
if ($this->podcast === null) {
if (! $this->podcast instanceof Podcast) {
$this->podcast = (new PodcastModel())->getPodcastByActorId($this->id);
}
return $this->podcast;
}
#[Override]
public function getAvatarImageUrl(): string
{
if ($this->podcast instanceof Podcast) {
return $this->podcast->cover->thumbnail_url;
}
return parent::getAvatarImageUrl();
}
#[Override]
public function getAvatarImageMimetype(): string
{
if ($this->podcast instanceof Podcast) {
return $this->podcast->cover->thumbnail_mimetype;
}
return parent::getAvatarImageMimetype();
}
}
......@@ -3,7 +3,7 @@
declare(strict_types=1);
/**
* @copyright 2020 Podlibre
* @copyright 2020 Ad Aures
* @license https://www.gnu.org/licenses/agpl-3.0.en.html AGPL3
* @link https://castopod.org/
*/
......@@ -29,16 +29,13 @@ class Category extends Entity
* @var array<string, string>
*/
protected $casts = [
'id' => 'integer',
'parent_id' => '?integer',
'code' => 'string',
'apple_category' => 'string',
'id' => 'integer',
'parent_id' => '?integer',
'code' => 'string',
'apple_category' => 'string',
'google_category' => 'string',
];
/**
* @noRector ReturnTypeDeclarationRector
*/
public function getParent(): ?self
{
if ($this->parent_id === null) {
......
<?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\Entities\Clip;
use App\Entities\Episode;
use App\Entities\Podcast;
use App\Models\EpisodeModel;
use App\Models\PodcastModel;
use CodeIgniter\Entity\Entity;
use CodeIgniter\Files\File;
use CodeIgniter\I18n\Time;
use CodeIgniter\Shield\Entities\User;
use Modules\Auth\Models\UserModel;
use Modules\Media\Entities\Audio;
use Modules\Media\Entities\Video;
use Modules\Media\Models\MediaModel;
/**
* @property int $id
* @property int $podcast_id
* @property Podcast $podcast
* @property int $episode_id
* @property Episode $episode
* @property string $title
* @property double $start_time
* @property double $end_time
* @property double $duration
* @property string $type
* @property int|null $media_id
* @property Video|Audio|null $media
* @property array<mixed>|null $metadata
* @property string $status
* @property string $logs
* @property User $user
* @property int $created_by
* @property int $updated_by
* @property Time|null $job_started_at
* @property Time|null $job_ended_at
*/
class BaseClip extends Entity
{
/**
* @var Video|Audio|null
*/
protected $media;
protected ?int $job_duration = null;
protected ?float $end_time = null;
/**
* @var array<int, string>
* @phpstan-var list<string>
*/
protected $dates = ['created_at', 'updated_at', 'job_started_at', 'job_ended_at'];
/**
* @var array<string, string>
*/
protected $casts = [
'id' => 'integer',
'podcast_id' => 'integer',
'episode_id' => 'integer',
'title' => 'string',
'start_time' => 'double',
'duration' => 'double',
'type' => 'string',
'media_id' => '?integer',
'metadata' => '?json-array',
'status' => 'string',
'logs' => 'string',
'created_by' => 'integer',
'updated_by' => 'integer',
];
/**
* @param array<string, mixed>|null $data
*/
public function __construct(?array $data = null)
{
parent::__construct($data);
}
public function getJobDuration(): ?int
{
if ($this->job_duration === null && $this->job_started_at && $this->job_ended_at) {
$this->job_duration = ($this->job_started_at->difference($this->job_ended_at))
->getSeconds();
}
return $this->job_duration;
}
public function getEndTime(): float
{
if ($this->end_time === null) {
$this->end_time = $this->start_time + $this->duration;
}
return $this->end_time;
}
public function getPodcast(): ?Podcast
{
return (new PodcastModel())->getPodcastById($this->podcast_id);
}
public function getEpisode(): ?Episode
{
return (new EpisodeModel())->getEpisodeById($this->episode_id);
}
public function getUser(): ?User
{
/** @var ?User */
return (new UserModel())->find($this->created_by);
}
public function setMedia(File $file, string $fileKey): static
{
if ($this->media_id !== null) {
$this->getMedia()
->setFile($file);
$this->getMedia()
->updated_by = $this->attributes['updated_by'];
(new MediaModel('audio'))->updateMedia($this->getMedia());
} else {
$media = new Audio([
'file_key' => $fileKey,
'language_code' => $this->getPodcast()
->language_code,
'uploaded_by' => $this->attributes['updated_by'],
'updated_by' => $this->attributes['updated_by'],
]);
$media->setFile($file);
$this->attributes['media_id'] = (new MediaModel())->saveMedia($media);
}
return $this;
}
public function getMedia(): Audio | Video | null
{
if ($this->media_id !== null && $this->media === null) {
$this->media = (new MediaModel($this->type))->getMediaById($this->media_id);
}
return $this->media;
}
}
......@@ -3,20 +3,14 @@
declare(strict_types=1);
/**
* @copyright 2020 Podlibre
* @copyright 2020 Ad Aures
* @license https://www.gnu.org/licenses/agpl-3.0.en.html AGPL3
* @link https://castopod.org/
*/
namespace App\Controllers\Admin;
namespace App\Entities\Clip;
use CodeIgniter\HTTP\RedirectResponse;
class HomeController extends BaseController
class Soundbite extends BaseClip
{
public function index(): RedirectResponse
{
session()->keepFlashdata('message');
return redirect()->route('podcast-list');
}
protected string $type = 'audio';
}
<?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\Entities\Clip;
use CodeIgniter\Files\File;
use Modules\Media\Entities\Video;
use Modules\Media\Models\MediaModel;
use Override;
/**
* @property array{name:string,preview:string} $theme
* @property string $format
*/
class VideoClip extends BaseClip
{
protected string $type = 'video';
/**
* @param array<string, mixed>|null $data
*/
public function __construct(?array $data = null)
{
parent::__construct($data);
if ($this->metadata !== null && $this->metadata !== []) {
$this->theme = $this->metadata['theme'];
$this->format = $this->metadata['format'];
}
}
/**
* @param array{name:string,preview:string} $theme
*/
public function setTheme(array $theme): self
{
// TODO: change?
$this->attributes['metadata'] = json_decode($this->attributes['metadata'] ?? '[]', true);
$this->attributes['theme'] = $theme;
$this->attributes['metadata']['theme'] = $theme;
$this->attributes['metadata'] = json_encode($this->attributes['metadata']);
return $this;
}
public function setFormat(string $format): self
{
$this->attributes['metadata'] = json_decode((string) $this->attributes['metadata'], true);
$this->attributes['format'] = $format;
$this->attributes['metadata']['format'] = $format;
$this->attributes['metadata'] = json_encode($this->attributes['metadata']);
return $this;
}
#[Override]
public function setMedia(File $file, string $fileKey): static
{
if ($this->attributes['media_id'] !== null) {
// media is already set, do nothing
return $this;
}
$video = new Video([
'file_key' => $fileKey,
'language_code' => $this->getPodcast()
->language_code,
'uploaded_by' => $this->attributes['created_by'],
'updated_by' => $this->attributes['created_by'],
]);
$video->setFile($file);
$this->attributes['media_id'] = (new MediaModel('video'))->saveMedia($video);
return $this;
}
}
......@@ -3,7 +3,7 @@
declare(strict_types=1);
/**
* @copyright 2020 Podlibre
* @copyright 2020 Ad Aures
* @license https://www.gnu.org/licenses/agpl-3.0.en.html AGPL3
* @link https://castopod.org/
*/
......@@ -45,12 +45,12 @@ class Credit extends Entity
* @var array<string, string>
*/
protected $casts = [
'podcast_id' => 'integer',
'episode_id' => '?integer',
'person_id' => 'integer',
'full_name' => 'string',
'podcast_id' => 'integer',
'episode_id' => '?integer',
'person_id' => 'integer',
'full_name' => 'string',
'person_group' => 'string',
'person_role' => 'string',
'person_role' => 'string',
];
public function getPerson(): ?Person
......@@ -59,7 +59,7 @@ class Credit extends Entity
throw new RuntimeException('Credit must have person_id before getting person.');
}
if ($this->person === null) {
if (! $this->person instanceof Person) {
$this->person = (new PersonModel())->getPersonById($this->person_id);
}
......@@ -72,7 +72,7 @@ class Credit extends Entity
throw new RuntimeException('Credit must have podcast_id before getting podcast.');
}
if ($this->podcast === null) {
if (! $this->podcast instanceof Podcast) {
$this->podcast = (new PodcastModel())->getPodcastById($this->podcast_id);
}
......@@ -85,7 +85,7 @@ class Credit extends Entity
throw new RuntimeException('Credit must have episode_id before getting episode.');
}
if ($this->episode === null) {
if (! $this->episode instanceof Episode) {
$this->episode = (new EpisodeModel())->getPublishedEpisodeById($this->podcast_id, $this->episode_id);
}
......@@ -98,6 +98,7 @@ class Credit extends Entity
return '';
}
/** @var string */
return lang("PersonsTaxonomy.persons.{$this->person_group}.label");
}
......@@ -111,6 +112,7 @@ class Credit extends Entity
return '';
}
/** @var string */
return lang("PersonsTaxonomy.persons.{$this->person_group}.roles.{$this->person_role}.label");
}
}
......@@ -3,57 +3,65 @@
declare(strict_types=1);
/**
* @copyright 2020 Podlibre
* @copyright 2020 Ad Aures
* @license https://www.gnu.org/licenses/agpl-3.0.en.html AGPL3
* @link https://castopod.org/
*/
namespace App\Entities;
use App\Libraries\SimpleRSSElement;
use App\Entities\Clip\Soundbite;
use App\Models\ClipModel;
use App\Models\EpisodeCommentModel;
use App\Models\EpisodeModel;
use App\Models\PersonModel;
use App\Models\PodcastModel;
use App\Models\SoundbiteModel;
use App\Models\StatusModel;
use App\Models\PostModel;
use CodeIgniter\Entity\Entity;
use CodeIgniter\Files\File;
use CodeIgniter\HTTP\Files\UploadedFile;
use CodeIgniter\I18n\Time;
use League\CommonMark\CommonMarkConverter;
use Exception;
use League\CommonMark\Environment\Environment;
use League\CommonMark\Extension\Autolink\AutolinkExtension;
use League\CommonMark\Extension\CommonMark\CommonMarkCoreExtension;
use League\CommonMark\Extension\DisallowedRawHtml\DisallowedRawHtmlExtension;
use League\CommonMark\Extension\SmartPunct\SmartPunctExtension;
use League\CommonMark\MarkdownConverter;
use Modules\Media\Entities\Audio;
use Modules\Media\Entities\Chapters;
use Modules\Media\Entities\Image;
use Modules\Media\Entities\Transcript;
use Modules\Media\Models\MediaModel;
use Override;
use RuntimeException;
/**
* @property int $id
* @property int $podcast_id
* @property Podcast $podcast
* @property ?string $preview_id
* @property string $preview_link
* @property string $link
* @property string $guid
* @property string $slug
* @property string $title
* @property File $audio_file
* @property string $audio_file_url
* @property string $audio_file_analytics_url
* @property string $audio_file_web_url
* @property string $audio_file_opengraph_url
* @property string $audio_file_path
* @property double $audio_file_duration
* @property string $audio_file_mimetype
* @property int $audio_file_size
* @property int $audio_file_header_size
* @property int $audio_id
* @property ?Audio $audio
* @property string $audio_url
* @property string $audio_web_url
* @property string $audio_opengraph_url
* @property string|null $description Holds text only description, striped of any markdown or html special characters
* @property string $description_markdown
* @property string $description_html
* @property Image $image
* @property string|null $image_path
* @property string|null $image_mimetype
* @property File|null $transcript_file
* @property string|null $transcript_file_url
* @property string|null $transcript_file_path
* @property string|null $transcript_file_remote_url
* @property File|null $chapters_file
* @property string|null $chapters_file_url
* @property string|null $chapters_file_path
* @property string|null $chapters_file_remote_url
* @property ?int $cover_id
* @property ?Image $cover
* @property int|null $transcript_id
* @property Transcript|null $transcript
* @property string|null $transcript_remote_url
* @property int|null $chapters_id
* @property Chapters|null $chapters
* @property string|null $chapters_remote_url
* @property string|null $parental_advisory
* @property int $number
* @property int $season_number
......@@ -63,48 +71,46 @@ use RuntimeException;
* @property string|null $location_name
* @property string|null $location_geo
* @property string|null $location_osm
* @property array|null $custom_rss
* @property string $custom_rss_string
* @property int $favourites_total
* @property int $reblogs_total
* @property int $statuses_total
* @property bool $is_published_on_hubs
* @property int $downloads_count
* @property int $posts_count
* @property int $comments_count
* @property EpisodeComment[]|null $comments
* @property bool $is_premium
* @property int $created_by
* @property int $updated_by
* @property string $publication_status;
* @property Time|null $published_at;
* @property Time $created_at;
* @property Time $updated_at;
* @property Time|null $deleted_at;
* @property string $publication_status
* @property Time|null $published_at
* @property Time $created_at
* @property Time $updated_at
*
* @property Person[] $persons;
* @property Soundbite[] $soundbites;
* @property string $embeddable_player_url;
* @property Person[] $persons
* @property Soundbite[] $soundbites
* @property string $embed_url
*/
class Episode extends Entity
{
protected Podcast $podcast;
protected string $link;
public string $link = '';
protected File $audio_file;
public string $audio_url = '';
protected string $audio_file_url;
public string $audio_web_url = '';
protected string $audio_file_analytics_url;
public string $audio_opengraph_url = '';
protected string $audio_file_web_url;
protected Podcast $podcast;
protected string $audio_file_opengraph_url;
protected ?Audio $audio = null;
protected string $embeddable_player_url;
protected string $embed_url = '';
protected Image $image;
protected ?Image $cover = null;
protected ?string $description = null;
protected File $transcript_file;
protected ?Transcript $transcript = null;
protected File $chapters_file;
protected ?Chapters $chapters = null;
/**
* @var Person[]|null
......@@ -117,237 +123,264 @@ class Episode extends Entity
protected ?array $soundbites = null;
/**
* @var Status[]|null
* @var Post[]|null
*/
protected ?array $statuses = null;
protected ?array $posts = null;
/**
* @var Status[]|null
* @var EpisodeComment[]|null
*/
protected ?array $comments = null;
protected ?Location $location = null;
protected string $custom_rss_string;
protected ?string $publication_status = null;
/**
* @var string[]
* @var array<int, string>
* @phpstan-var list<string>
*/
protected $dates = ['published_at', 'created_at', 'updated_at', 'deleted_at'];
protected $dates = ['published_at', 'created_at', 'updated_at'];
/**
* @var array<string, string>
*/
protected $casts = [
'id' => 'integer',
'podcast_id' => 'integer',
'guid' => 'string',
'slug' => 'string',
'title' => 'string',
'audio_file_path' => 'string',
'audio_file_duration' => 'double',
'audio_file_mimetype' => 'string',
'audio_file_size' => 'integer',
'audio_file_header_size' => 'integer',
'description_markdown' => 'string',
'description_html' => 'string',
'image_path' => '?string',
'image_mimetype' => '?string',
'transcript_file_path' => '?string',
'transcript_file_remote_url' => '?string',
'chapters_file_path' => '?string',
'chapters_file_remote_url' => '?string',
'parental_advisory' => '?string',
'number' => '?integer',
'season_number' => '?integer',
'type' => 'string',
'is_blocked' => 'boolean',
'location_name' => '?string',
'location_geo' => '?string',
'location_osm' => '?string',
'custom_rss' => '?json-array',
'favourites_total' => 'integer',
'reblogs_total' => 'integer',
'statuses_total' => 'integer',
'created_by' => 'integer',
'updated_by' => 'integer',
'id' => 'integer',
'podcast_id' => 'integer',
'preview_id' => '?string',
'guid' => 'string',
'slug' => 'string',
'title' => 'string',
'audio_id' => 'integer',
'description_markdown' => 'string',
'description_html' => 'string',
'cover_id' => '?integer',
'transcript_id' => '?integer',
'transcript_remote_url' => '?string',
'chapters_id' => '?integer',
'chapters_remote_url' => '?string',
'parental_advisory' => '?string',
'number' => '?integer',
'season_number' => '?integer',
'type' => 'string',
'is_blocked' => 'boolean',
'location_name' => '?string',
'location_geo' => '?string',
'location_osm' => '?string',
'is_published_on_hubs' => 'boolean',
'downloads_count' => 'integer',
'posts_count' => 'integer',
'comments_count' => 'integer',
'is_premium' => 'boolean',
'created_by' => 'integer',
'updated_by' => 'integer',
];
/**
* Saves an episode image
* @param array<string, mixed> $data
*/
public function setImage(?Image $image = null): static
#[Override]
public function injectRawData(array $data): static
{
if ($image === null) {
return $this;
}
parent::injectRawData($data);
// Save image
$image->saveImage('podcasts/' . $this->getPodcast()->handle, $this->attributes['slug']);
$this->link = url_to('episode', esc($this->getPodcast()->handle, 'url'), esc($this->attributes['slug'], 'url'));
$this->attributes['image_mimetype'] = $image->mimetype;
$this->attributes['image_path'] = $image->path;
$this->audio_url = url_to(
'episode-audio',
$this->getPodcast()
->handle,
$this->slug,
$this->getAudio()
->file_extension,
);
$this->audio_opengraph_url = $this->audio_url . '?_from=-+Open+Graph+-';
$this->audio_web_url = $this->audio_url . '?_from=-+Website+-';
return $this;
}
public function getImage(): Image
public function setCover(UploadedFile | File|null $file = null): self
{
if ($imagePath = $this->attributes['image_path']) {
return new Image(null, $imagePath, $this->attributes['image_mimetype']);
if (! $file instanceof File || ($file instanceof UploadedFile && ! $file->isValid())) {
return $this;
}
return $this->getPodcast()
->image;
}
/**
* Saves an audio file
*/
public function setAudioFile(UploadedFile | File $audioFile): static
{
helper(['media', 'id3']);
$audioMetadata = get_file_tags($audioFile);
$this->attributes['audio_file_path'] = save_media(
$audioFile,
'podcasts/' . $this->getPodcast()->handle,
$this->attributes['slug'],
);
$this->attributes['audio_file_duration'] =
$audioMetadata['playtime_seconds'];
$this->attributes['audio_file_mimetype'] = $audioMetadata['mime_type'];
$this->attributes['audio_file_size'] = $audioMetadata['filesize'];
$this->attributes['audio_file_header_size'] =
$audioMetadata['avdataoffset'];
if (array_key_exists('cover_id', $this->attributes) && $this->attributes['cover_id'] !== null) {
$this->getCover()
->setFile($file);
$this->getCover()
->updated_by = $this->attributes['updated_by'];
(new MediaModel('image'))->updateMedia($this->getCover());
} else {
$cover = new Image([
'file_key' => 'podcasts/' . $this->getPodcast()->handle . '/' . $this->attributes['slug'] . '.' . $file->getExtension(),
'sizes' => config('Images')
->podcastCoverSizes,
'uploaded_by' => $this->attributes['updated_by'],
'updated_by' => $this->attributes['updated_by'],
]);
$cover->setFile($file);
$this->attributes['cover_id'] = (new MediaModel('image'))->saveMedia($cover);
}
return $this;
}
/**
* Saves an episode transcript file
*/
public function setTranscriptFile(UploadedFile | File $transcriptFile): static
public function getCover(): Image
{
helper('media');
if ($this->cover instanceof Image) {
return $this->cover;
}
$this->attributes['transcript_file_path'] = save_media(
$transcriptFile,
'podcasts/' . $this->getPodcast()
->handle,
$this->attributes['slug'] . '-transcript',
);
if ($this->cover_id === null) {
$this->cover = $this->getPodcast()
->getCover();
return $this;
return $this->cover;
}
$this->cover = (new MediaModel('image'))->getMediaById($this->cover_id);
return $this->cover;
}
/**
* Saves an episode chapters file
*/
public function setChaptersFile(UploadedFile | File $chaptersFile): static
public function setAudio(UploadedFile | File|null $file = null): self
{
helper('media');
if (! $file instanceof File || ($file instanceof UploadedFile && ! $file->isValid())) {
return $this;
}
$this->attributes['chapters_file_path'] = save_media(
$chaptersFile,
'podcasts/' . $this->getPodcast()
->handle,
$this->attributes['slug'] . '-chapters',
);
if ($this->audio_id !== 0) {
$this->getAudio()
->setFile($file);
$this->getAudio()
->updated_by = $this->attributes['updated_by'];
(new MediaModel('audio'))->updateMedia($this->getAudio());
} else {
$audio = new Audio([
'file_key' => 'podcasts/' . $this->getPodcast()->handle . '/' . $file->getRandomName(),
'language_code' => $this->getPodcast()
->language_code,
'uploaded_by' => $this->attributes['updated_by'],
'updated_by' => $this->attributes['updated_by'],
]);
$audio->setFile($file);
$this->attributes['audio_id'] = (new MediaModel())->saveMedia($audio);
}
return $this;
}
public function getAudioFile(): File
public function getAudio(): Audio
{
helper('media');
if (! $this->audio instanceof Audio) {
$this->audio = (new MediaModel('audio'))->getMediaById($this->audio_id);
}
return new File(media_path($this->audio_file_path));
return $this->audio;
}
public function getTranscriptFile(): ?File
public function setTranscript(UploadedFile | File|null $file = null): self
{
if ($this->attributes['transcript_file_path']) {
helper('media');
if (! $file instanceof File || ($file instanceof UploadedFile && ! $file->isValid())) {
return $this;
}
return new File(media_path($this->attributes['transcript_file_path']));
if ($this->getTranscript() instanceof Transcript) {
$this->getTranscript()
->setFile($file);
$this->getTranscript()
->updated_by = $this->attributes['updated_by'];
(new MediaModel('transcript'))->updateMedia($this->getTranscript());
} else {
$transcript = new Transcript([
'file_key' => 'podcasts/' . $this->getPodcast()->handle . '/' . $this->attributes['slug'] . '-transcript.' . $file->getExtension(),
'language_code' => $this->getPodcast()
->language_code,
'uploaded_by' => $this->attributes['updated_by'],
'updated_by' => $this->attributes['updated_by'],
]);
$transcript->setFile($file);
$this->attributes['transcript_id'] = (new MediaModel('transcript'))->saveMedia($transcript);
}
return null;
return $this;
}
public function getChaptersFile(): ?File
public function getTranscript(): ?Transcript
{
if ($this->attributes['chapters_file_path']) {
helper('media');
return new File(media_path($this->attributes['chapters_file_path']));
if ($this->transcript_id !== null && ! $this->transcript instanceof Transcript) {
$this->transcript = (new MediaModel('transcript'))->getMediaById($this->transcript_id);
}
return null;
return $this->transcript;
}
public function getAudioFileUrl(): string
public function setChapters(UploadedFile | File|null $file = null): self
{
helper('media');
if (! $file instanceof File || ($file instanceof UploadedFile && ! $file->isValid())) {
return $this;
}
return media_base_url($this->audio_file_path);
}
if ($this->getChapters() instanceof Chapters) {
$this->getChapters()
->setFile($file);
$this->getChapters()
->updated_by = $this->attributes['updated_by'];
(new MediaModel('chapters'))->updateMedia($this->getChapters());
} else {
$chapters = new Chapters([
'file_key' => 'podcasts/' . $this->getPodcast()->handle . '/' . $this->attributes['slug'] . '-chapters' . '.' . $file->getExtension(),
'language_code' => $this->getPodcast()
->language_code,
'uploaded_by' => $this->attributes['updated_by'],
'updated_by' => $this->attributes['updated_by'],
]);
$chapters->setFile($file);
$this->attributes['chapters_id'] = (new MediaModel('chapters'))->saveMedia($chapters);
}
public function getAudioFileAnalyticsUrl(): string
{
helper('analytics');
// remove 'podcasts/' from audio file path
$strippedAudioFilePath = substr($this->audio_file_path, 9);
return generate_episode_analytics_url(
$this->podcast_id,
$this->id,
$strippedAudioFilePath,
$this->audio_file_duration,
$this->audio_file_size,
$this->audio_file_header_size,
$this->published_at,
);
return $this;
}
public function getAudioFileWebUrl(): string
public function getChapters(): ?Chapters
{
return $this->getAudioFileAnalyticsUrl() . '?_from=-+Website+-';
}
if ($this->chapters_id !== null && ! $this->chapters instanceof Chapters) {
$this->chapters = (new MediaModel('chapters'))->getMediaById($this->chapters_id);
}
public function getAudioFileOpengraphUrl(): string
{
return $this->getAudioFileAnalyticsUrl() . '?_from=-+Open+Graph+-';
return $this->chapters;
}
/**
* Gets transcript url from transcript file uri if it exists or returns the transcript_file_remote_url which can be
* null.
* Gets transcript url from transcript file uri if it exists or returns the transcript_remote_url which can be null.
*/
public function getTranscriptFileUrl(): ?string
public function getTranscriptUrl(): ?string
{
if ($this->attributes['transcript_file_path']) {
return media_base_url($this->attributes['transcript_file_path']);
if ($this->transcript instanceof Transcript) {
return $this->transcript->file_url;
}
return $this->attributes['transcript_file_remote_url'];
return $this->transcript_remote_url;
}
/**
* Gets chapters file url from chapters file uri if it exists or returns the chapters_file_remote_url which can be
* null.
* Gets chapters file url from chapters file uri if it exists or returns the chapters_remote_url which can be null.
*/
public function getChaptersFileUrl(): ?string
{
if ($this->chapters_file_path) {
return media_base_url($this->chapters_file_path);
if ($this->chapters instanceof Chapters) {
return $this->chapters->file_url;
}
return $this->chapters_file_remote_url;
return $this->chapters_remote_url;
}
/**
......@@ -369,7 +402,7 @@ class Episode extends Entity
}
/**
* Returns the episode’s soundbites
* Returns the episode’s clips
*
* @return Soundbite[]
*/
......@@ -380,30 +413,30 @@ class Episode extends Entity
}
if ($this->soundbites === null) {
$this->soundbites = (new SoundbiteModel())->getEpisodeSoundbites($this->getPodcast() ->id, $this->id);
$this->soundbites = (new ClipModel())->getEpisodeSoundbites($this->getPodcast()->id, $this->id);
}
return $this->soundbites;
}
/**
* @return Status[]
* @return Post[]
*/
public function getStatuses(): array
public function getPosts(): array
{
if ($this->id === null) {
throw new RuntimeException('Episode must be created before getting statuses.');
throw new RuntimeException('Episode must be created before getting posts.');
}
if ($this->statuses === null) {
$this->statuses = (new StatusModel())->getEpisodeStatuses($this->id);
if ($this->posts === null) {
$this->posts = (new PostModel())->getEpisodePosts($this->id);
}
return $this->statuses;
return $this->posts;
}
/**
* @return Status[]
* @return EpisodeComment[]
*/
public function getComments(): array
{
......@@ -412,35 +445,22 @@ class Episode extends Entity
}
if ($this->comments === null) {
$this->comments = (new StatusModel())->getEpisodeComments($this->id);
$this->comments = (new EpisodeCommentModel())->getEpisodeComments($this->id);
}
return $this->comments;
}
public function getLink(): string
public function getEmbedUrl(?string $theme = null): string
{
return url_to('episode', $this->getPodcast()->name, $this->attributes['slug']);
}
public function getEmbeddablePlayerUrl(string $theme = null): string
{
return base_url(
$theme
? route_to(
'embeddable-player-theme',
$this->getPodcast()
->handle,
$this->attributes['slug'],
$theme,
)
: route_to('embeddable-player', $this->getPodcast()->handle, $this->attributes['slug']),
);
return $theme
? url_to('embed-theme', esc($this->getPodcast()->handle), esc($this->attributes['slug']), $theme)
: url_to('embed', esc($this->getPodcast()->handle), esc($this->attributes['slug']));
}
public function setGuid(?string $guid = null): static
{
$this->attributes['guid'] = $guid === null ? $this->getLink() : $guid;
$this->attributes['guid'] = $guid ?? $this->link;
return $this;
}
......@@ -452,50 +472,30 @@ class Episode extends Entity
public function setDescriptionMarkdown(string $descriptionMarkdown): static
{
$converter = new CommonMarkConverter([
'html_input' => 'strip',
$config = [
'html_input' => 'escape',
'allow_unsafe_links' => false,
]);
];
$this->attributes['description_markdown'] = $descriptionMarkdown;
$this->attributes['description_html'] = $converter->convertToHtml($descriptionMarkdown);
$environment = new Environment($config);
$environment->addExtension(new CommonMarkCoreExtension());
$environment->addExtension(new AutolinkExtension());
$environment->addExtension(new SmartPunctExtension());
$environment->addExtension(new DisallowedRawHtmlExtension());
return $this;
}
public function getDescriptionHtml(?string $serviceSlug = null): string
{
$descriptionHtml = '';
if (
$this->getPodcast()
->partner_id !== null &&
$this->getPodcast()
->partner_link_url !== null &&
$this->getPodcast()
->partner_image_url !== null
) {
$descriptionHtml .= "<div><a href=\"{$this->getPartnerLink(
$serviceSlug,
)}\" rel=\"sponsored noopener noreferrer\" target=\"_blank\"><img src=\"{$this->getPartnerImageUrl(
$serviceSlug,
)}\" alt=\"Partner image\" /></a></div>";
}
$converter = new MarkdownConverter($environment);
$descriptionHtml .= $this->attributes['description_html'];
if ($this->getPodcast()->episode_description_footer_html) {
$descriptionHtml .= "<footer>{$this->getPodcast()
->episode_description_footer_html}</footer>";
}
$this->attributes['description_markdown'] = $descriptionMarkdown;
$this->attributes['description_html'] = $converter->convert($descriptionMarkdown);
return $descriptionHtml;
return $this;
}
public function getDescription(): string
{
if ($this->description === null) {
$this->description = trim(
preg_replace('~\s+~', ' ', strip_tags($this->attributes['description_html'])),
(string) preg_replace('~\s+~', ' ', strip_tags((string) $this->attributes['description_html'])),
);
}
......@@ -505,8 +505,10 @@ class Episode extends Entity
public function getPublicationStatus(): string
{
if ($this->publication_status === null) {
if ($this->published_at === null) {
if (! $this->published_at instanceof Time) {
$this->publication_status = 'not_published';
} elseif ($this->getPodcast()->publication_status !== 'published') {
$this->publication_status = 'with_podcast';
} elseif ($this->published_at->isBefore(Time::now())) {
$this->publication_status = 'published';
} else {
......@@ -522,7 +524,7 @@ class Episode extends Entity
*/
public function setLocation(?Location $location = null): static
{
if ($location === null) {
if (! $location instanceof Location) {
$this->attributes['location_name'] = null;
$this->attributes['location_geo'] = null;
$this->attributes['location_osm'] = null;
......@@ -550,89 +552,36 @@ class Episode extends Entity
return null;
}
if ($this->location === null) {
if (! $this->location instanceof Location) {
$this->location = new Location($this->location_name, $this->location_geo, $this->location_osm);
}
return $this->location;
}
/**
* Get custom rss tag as XML String
*/
public function getCustomRssString(): string
public function getPreviewLink(): string
{
if ($this->custom_rss === null) {
return '';
}
helper('rss');
if ($this->preview_id === null) {
// generate preview id
if (! $previewUUID = (new EpisodeModel())->setEpisodePreviewId($this->id)) {
throw new Exception('Could not set episode preview id');
}
$xmlNode = (new SimpleRSSElement(
'<?xml version="1.0" encoding="utf-8"?><rss xmlns:itunes="http://www.itunes.com/dtds/podcast-1.0.dtd" xmlns:podcast="https://github.com/Podcastindex-org/podcast-namespace/blob/main/docs/1.0.md" xmlns:content="http://purl.org/rss/1.0/modules/content/" version="2.0"/>',
))
->addChild('channel')
->addChild('item');
array_to_rss([
'elements' => $this->custom_rss,
], $xmlNode);
$this->preview_id = $previewUUID;
}
return str_replace(['<item>', '</item>'], '', $xmlNode->asXML());
return url_to('episode-preview', (string) $this->preview_id);
}
/**
* Saves custom rss tag into json
* Returns the episode's clip count
*/
public function setCustomRssString(?string $customRssString = null): static
{
if ($customRssString === '') {
$this->attributes['custom_rss'] = null;
return $this;
}
helper('rss');
$customRssArray = rss_to_array(
simplexml_load_string(
'<?xml version="1.0" encoding="utf-8"?><rss xmlns:itunes="http://www.itunes.com/dtds/podcast-1.0.dtd" xmlns:podcast="https://github.com/Podcastindex-org/podcast-namespace/blob/main/docs/1.0.md" xmlns:content="http://purl.org/rss/1.0/modules/content/" version="2.0"><channel><item>' .
$customRssString .
'</item></channel></rss>',
),
)['elements'][0]['elements'][0];
if (array_key_exists('elements', $customRssArray)) {
$this->attributes['custom_rss'] = json_encode($customRssArray['elements']);
} else {
$this->attributes['custom_rss'] = null;
}
return $this;
}
public function getPartnerLink(?string $serviceSlug = null): string
public function getClipCount(): int|string
{
$partnerLink =
rtrim($this->getPodcast()->partner_link_url, '/') .
'?pid=' .
$this->getPodcast()
->partner_id .
'&guid=' .
urlencode($this->attributes['guid']);
if ($serviceSlug !== null) {
$partnerLink .= '&_from=' . $serviceSlug;
if ($this->id === null) {
throw new RuntimeException('Episode must be created before getting number of video clips.');
}
return $partnerLink;
}
public function getPartnerImageUrl(string $serviceSlug = null): string
{
return rtrim($this->getPodcast()->partner_image_url, '/') .
'?pid=' .
$this->getPodcast()
->partner_id .
'&guid=' .
urlencode($this->attributes['guid']) .
($serviceSlug !== null ? '&_from=' . $serviceSlug : '');
return (new ClipModel())->getClipCount($this->podcast_id, $this->id);
}
}
<?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\Entities;
use App\Models\ActorModel;
use App\Models\EpisodeCommentModel;
use App\Models\EpisodeModel;
use CodeIgniter\I18n\Time;
use Michalsn\Uuid\UuidEntity;
use RuntimeException;
/**
* @property string $id
* @property string $uri
* @property int $episode_id
* @property Episode|null $episode
* @property int $actor_id
* @property Actor|null $actor
* @property string $in_reply_to_id
* @property EpisodeComment|null $reply_to_comment
* @property string $message
* @property string $message_html
* @property int $likes_count
* @property int $replies_count
* @property Time $created_at
* @property int $created_by
*
* @property EpisodeComment[] $replies
*/
class EpisodeComment extends UuidEntity
{
protected ?Episode $episode = null;
protected ?Actor $actor = null;
protected ?EpisodeComment $reply_to_comment = null;
/**
* @var EpisodeComment[]|null
*/
protected ?array $replies = null;
protected bool $has_replies = false;
/**
* @var array<int, string>
* @phpstan-var list<string>
*/
protected $dates = ['created_at'];
/**
* @var array<string, string>
*/
protected $casts = [
'id' => 'string',
'uri' => 'string',
'episode_id' => 'integer',
'actor_id' => 'integer',
'in_reply_to_id' => '?string',
'message' => 'string',
'message_html' => 'string',
'likes_count' => 'integer',
'replies_count' => 'integer',
'created_by' => 'integer',
'is_from_post' => 'boolean',
];
public function getEpisode(): ?Episode
{
if ($this->episode_id === null) {
throw new RuntimeException('Comment must have an episode_id before getting episode.');
}
if (! $this->episode instanceof Episode) {
$this->episode = (new EpisodeModel())->getEpisodeById($this->episode_id);
}
return $this->episode;
}
/**
* Returns the comment's actor
*/
public function getActor(): ?Actor
{
if ($this->actor_id === null) {
throw new RuntimeException('Comment must have an actor_id before getting actor.');
}
if (! $this->actor instanceof Actor) {
$this->actor = model(ActorModel::class, false)
->getActorById($this->actor_id);
}
return $this->actor;
}
/**
* @return EpisodeComment[]
*/
public function getReplies(): array
{
if ($this->id === null) {
throw new RuntimeException('Comment must be created before getting replies.');
}
if ($this->replies === null) {
$this->replies = (new EpisodeCommentModel())->getCommentReplies($this->id);
}
return $this->replies;
}
public function getHasReplies(): bool
{
return $this->getReplies() !== [];
}
public function getReplyToComment(): ?self
{
if ($this->in_reply_to_id === null) {
throw new RuntimeException('Comment is not a reply.');
}
if (! $this->reply_to_comment instanceof self) {
$this->reply_to_comment = model(EpisodeCommentModel::class, false)
->getCommentById($this->in_reply_to_id);
}
return $this->reply_to_comment;
}
public function setMessage(string $message): static
{
helper('fediverse');
$messageWithoutTags = strip_tags($message);
$this->attributes['message'] = $messageWithoutTags;
$this->attributes['message_html'] = str_replace("\n", '<br />', linkify($messageWithoutTags));
return $this;
}
}
<?php
declare(strict_types=1);
/**
* @copyright 2021 Podlibre
* @license https://www.gnu.org/licenses/agpl-3.0.en.html AGPL3
* @link https://castopod.org/
*/
namespace App\Entities;
use CodeIgniter\Entity\Entity;
use CodeIgniter\Files\File;
use Config\Images;
use Config\Services;
use RuntimeException;
/**
* @property File|null $file
* @property string $dirname
* @property string $filename
* @property string $extension
* @property string $mimetype
* @property string $path
* @property string $url
* @property string $thumbnail_path
* @property string $thumbnail_url
* @property string $medium_path
* @property string $medium_url
* @property string $large_path
* @property string $large_url
* @property string $feed_path
* @property string $feed_url
* @property string $id3_path
* @property string $id3_url
*/
class Image extends Entity
{
protected Images $config;
protected ?File $file = null;
protected string $dirname;
protected string $filename;
protected string $extension;
public function __construct(?File $file, string $path = '', string $mimetype = '')
{
if ($file === null && $path === '') {
throw new RuntimeException('File or path must be set to create an Image.');
}
$this->config = config('Images');
$dirname = '';
$filename = '';
$extension = '';
if ($file !== null) {
$dirname = $file->getPath();
$filename = $file->getBasename();
$extension = $file->getExtension();
$mimetype = $file->getMimeType();
}
if ($path !== '') {
[
'filename' => $filename,
'dirname' => $dirname,
'extension' => $extension,
] = pathinfo($path);
}
$this->file = $file;
$this->dirname = $dirname;
$this->filename = $filename;
$this->extension = $extension;
$this->mimetype = $mimetype;
}
public function getFile(): File
{
if ($this->file === null) {
$this->file = new File($this->path);
}
return $this->file;
}
public function getPath(): string
{
return $this->dirname . '/' . $this->filename . '.' . $this->extension;
}
public function getUrl(): string
{
helper('media');
return media_base_url($this->path);
}
public function getThumbnailPath(): string
{
return $this->dirname .
'/' .
$this->filename .
$this->config->thumbnailSuffix .
'.' .
$this->extension;
}
public function getThumbnailUrl(): string
{
helper('media');
return media_base_url($this->thumbnail_path);
}
public function getMediumPath(): string
{
return $this->dirname .
'/' .
$this->filename .
$this->config->mediumSuffix .
'.' .
$this->extension;
}
public function getMediumUrl(): string
{
helper('media');
return media_base_url($this->medium_path);
}
public function getLargePath(): string
{
return $this->dirname .
'/' .
$this->filename .
$this->config->largeSuffix .
'.' .
$this->extension;
}
public function getLargeUrl(): string
{
helper('media');
return media_base_url($this->large_path);
}
public function getFeedPath(): string
{
return $this->dirname .
'/' .
$this->filename .
$this->config->feedSuffix .
'.' .
$this->extension;
}
public function getFeedUrl(): string
{
helper('media');
return media_base_url($this->feed_path);
}
public function getId3Path(): string
{
return $this->dirname .
'/' .
$this->filename .
$this->config->id3Suffix .
'.' .
$this->extension;
}
public function getId3Url(): string
{
helper('media');
return media_base_url($this->id3_path);
}
public function saveImage(string $dirname, string $filename): void
{
helper('media');
$this->dirname = $dirname;
$this->filename = $filename;
save_media($this->file, $this->dirname, $this->filename);
$imageService = Services::image();
$thumbnailSize = $this->config->thumbnailSize;
$mediumSize = $this->config->mediumSize;
$largeSize = $this->config->largeSize;
$feedSize = $this->config->feedSize;
$id3Size = $this->config->id3Size;
$imageService
->withFile(media_path($this->path))
->resize($thumbnailSize, $thumbnailSize)
->save(media_path($this->thumbnail_path));
$imageService
->withFile(media_path($this->path))
->resize($mediumSize, $mediumSize)
->save(media_path($this->medium_path));
$imageService
->withFile(media_path($this->path))
->resize($largeSize, $largeSize)
->save(media_path($this->large_path));
$imageService
->withFile(media_path($this->path))
->resize($feedSize, $feedSize)
->save(media_path($this->feed_path));
$imageService
->withFile(media_path($this->path))
->resize($id3Size, $id3Size)
->save(media_path($this->id3_path));
}
}
......@@ -3,7 +3,7 @@
declare(strict_types=1);
/**
* @copyright 2020 Podlibre
* @copyright 2020 Ad Aures
* @license https://www.gnu.org/licenses/agpl-3.0.en.html AGPL3
* @link https://castopod.org/
*/
......@@ -22,7 +22,7 @@ class Language extends Entity
* @var array<string, string>
*/
protected $casts = [
'code' => 'string',
'code' => 'string',
'native_name' => 'string',
];
}
<?php
declare(strict_types=1);
/**
* @copyright 2021 Ad Aures
* @license https://www.gnu.org/licenses/agpl-3.0.en.html AGPL3
* @link https://castopod.org/
*/
namespace App\Entities;
use Michalsn\Uuid\UuidEntity;
/**
* @property int $actor_id
* @property string $comment_id
*/
class Like extends UuidEntity
{
/**
* @var string[]
*/
protected $uuids = ['comment_id'];
/**
* @var array<string, string>
*/
protected $casts = [
'actor_id' => 'integer',
'comment_id' => 'string',
];
}
......@@ -3,7 +3,7 @@
declare(strict_types=1);
/**
* @copyright 2021 Podlibre
* @copyright 2021 Ad Aures
* @license https://www.gnu.org/licenses/agpl-3.0.en.html AGPL3
* @link https://castopod.org/
*/
......@@ -11,7 +11,6 @@ declare(strict_types=1);
namespace App\Entities;
use CodeIgniter\Entity\Entity;
use Config\Services;
/**
* @property string $url
......@@ -23,15 +22,9 @@ use Config\Services;
*/
class Location extends Entity
{
/**
* @var string
*/
private const OSM_URL = 'https://www.openstreetmap.org/';
private const string OSM_URL = 'https://www.openstreetmap.org/';
/**
* @var string
*/
private const NOMINATIM_URL = 'https://nominatim.openstreetmap.org/';
private const string NOMINATIM_URL = 'https://nominatim.openstreetmap.org/';
public function __construct(
protected string $name,
......@@ -42,14 +35,18 @@ class Location extends Entity
$longitude = null;
if ($geo !== null) {
$geoArray = explode(',', substr($geo, 4));
$latitude = floatval($geoArray[0]);
$longitude = floatval($geoArray[1]);
if (count($geoArray) === 2) {
$latitude = (float) $geoArray[0];
$longitude = (float) $geoArray[1];
}
}
parent::__construct([
'name' => $name,
'geo' => $geo,
'osm' => $osm,
'latitude' => $latitude,
'name' => $name,
'geo' => $geo,
'osm' => $osm,
'latitude' => $latitude,
'longitude' => $longitude,
]);
}
......@@ -81,7 +78,7 @@ class Location extends Entity
*/
public function fetchOsmLocation(): static
{
$client = Services::curlrequest();
$client = service('curlrequest');
$response = $client->request(
'GET',
......@@ -92,12 +89,12 @@ class Location extends Entity
[
'headers' => [
'User-Agent' => 'Castopod/' . CP_VERSION,
'Accept' => 'application/json',
'Accept' => 'application/json',
],
],
);
$places = json_decode($response->getBody(), false, 512, JSON_THROW_ON_ERROR);
$places = json_decode((string) $response->getBody(), false, 512, JSON_THROW_ON_ERROR);
if ($places === []) {
return $this;
......@@ -105,16 +102,16 @@ class Location extends Entity
if (property_exists($places[0], 'lat') && $places[0]->lat !== null && (property_exists(
$places[0],
'lon'
'lon',
) && $places[0]->lon !== null)) {
$this->attributes['geo'] = "geo:{$places[0]->lat},{$places[0]->lon}";
}
if (property_exists($places[0], 'osm_type') && $places[0]->osm_type !== null && (property_exists(
$places[0],
'osm_id'
'osm_id',
) && $places[0]->osm_id !== null)) {
$this->attributes['osm'] = strtoupper(substr($places[0]->osm_type, 0, 1)) . $places[0]->osm_id;
$this->attributes['osm'] = strtoupper(substr((string) $places[0]->osm_type, 0, 1)) . $places[0]->osm_id;
}
return $this;
......