Commit 8acd011f authored by Benjamin Bellamy's avatar Benjamin Bellamy 💬
Browse files

feat(person): add podcastindex.org namespace person tag

parent 17e1e94a
Loading
Loading
Loading
Loading
Loading
+12 −0
Original line number Diff line number Diff line
@@ -30,6 +30,9 @@ $RECYCLE.BIN/
# Linux
*~

# vim
*.swp

# KDE directory preferences
.directory

@@ -135,6 +138,7 @@ node_modules
# public folder
public/*
!public/media
!public/media/~person
!public/.htaccess
!public/favicon.ico
!public/index.php
@@ -144,6 +148,14 @@ public/*
public/media/*
!public/media/index.html

# public person folder
public/media/~person/*
!public/media/~person/index.html

# Generated files
app/Language/en/PersonsTaxonomy.php
app/Language/fr/PersonsTaxonomy.php

#-------------------------
# Docker volumes
#-------------------------
+75 −0
Original line number Diff line number Diff line
@@ -85,6 +85,37 @@ $routes->group(
            'as' => 'my-podcasts',
        ]);

        $routes->group('persons', function ($routes) {
            $routes->get('/', 'Person', [
                'as' => 'person-list',
                'filter' => 'permission:person-list',
            ]);
            $routes->get('new', 'Person::create', [
                'as' => 'person-create',
                'filter' => 'permission:person-create',
            ]);
            $routes->post('new', 'Person::attemptCreate', [
                'filter' => 'permission:person-create',
            ]);
            $routes->group('(:num)', function ($routes) {
                $routes->get('/', 'Person::view/$1', [
                    'as' => 'person-view',
                    'filter' => 'permission:person-view',
                ]);
                $routes->get('edit', 'Person::edit/$1', [
                    'as' => 'person-edit',
                    'filter' => 'permission:person-edit',
                ]);
                $routes->post('edit', 'Person::attemptEdit/$1', [
                    'filter' => 'permission:person-edit',
                ]);
                $routes->add('delete', 'Person::delete/$1', [
                    'as' => 'person-delete',
                    'filter' => 'permission:person-delete',
                ]);
            });
        });

        // Podcasts
        $routes->group('podcasts', function ($routes) {
            $routes->get('/', 'Podcast::list', [
@@ -124,6 +155,25 @@ $routes->group(
                    'filter' => 'permission:podcasts-delete',
                ]);

                $routes->group('persons', function ($routes) {
                    $routes->get('/', 'PodcastPerson/$1', [
                        'as' => 'podcast-person-manage',
                        'filter' => 'permission:podcast-edit',
                    ]);
                    $routes->post('/', 'PodcastPerson::attemptAdd/$1', [
                        'filter' => 'permission:podcast-edit',
                    ]);

                    $routes->get(
                        '(:num)/remove',
                        'PodcastPerson::remove/$1/$2',
                        [
                            'as' => 'podcast-person-remove',
                            'filter' => 'permission:podcast-edit',
                        ]
                    );
                });

                $routes->group('analytics', function ($routes) {
                    $routes->get('/', 'Podcast::viewAnalytics/$1', [
                        'as' => 'podcast-analytics',
@@ -276,6 +326,30 @@ $routes->group(
                                'filter' => 'permission:podcast_episodes-edit',
                            ]
                        );

                        $routes->group('persons', function ($routes) {
                            $routes->get('/', 'EpisodePerson/$1/$2', [
                                'as' => 'episode-person-manage',
                                'filter' => 'permission:podcast_episodes-edit',
                            ]);
                            $routes->post(
                                '/',
                                'EpisodePerson::attemptAdd/$1/$2',
                                [
                                    'filter' =>
                                        'permission:podcast_episodes-edit',
                                ]
                            );
                            $routes->get(
                                '(:num)/remove',
                                'EpisodePerson::remove/$1/$2/$3',
                                [
                                    'as' => 'episode-person-remove',
                                    'filter' =>
                                        'permission:podcast_episodes-edit',
                                ]
                            );
                        });
                    });
                });

@@ -497,6 +571,7 @@ $routes->group('@(:podcastName)', function ($routes) {
    $routes->head('feed.xml', 'Feed/$1', ['as' => 'podcast_feed']);
    $routes->get('feed.xml', 'Feed/$1', ['as' => 'podcast_feed']);
});
$routes->get('/credits', 'Page::credits', ['as' => 'credits']);
$routes->get('/(:slug)', 'Page/$1', ['as' => 'page']);

/**
+111 −0
Original line number Diff line number Diff line
<?php

/**
 * @copyright  2020 Podlibre
 * @license    https://www.gnu.org/licenses/agpl-3.0.en.html AGPL3
 * @link       https://castopod.org/
 */

namespace App\Controllers\Admin;

use App\Models\EpisodePersonModel;
use App\Models\PodcastModel;
use App\Models\EpisodeModel;
use App\Models\PersonModel;

class EpisodePerson extends BaseController
{
    /**
     * @var \App\Entities\Podcast
     */
    protected $podcast;

    /**
     * @var \App\Entities\Episode
     */
    protected $episode;

    public function _remap($method, ...$params)
    {
        if (count($params) > 1) {
            if (
                !($this->podcast = (new PodcastModel())->getPodcastById(
                    $params[0]
                ))
            ) {
                throw \CodeIgniter\Exceptions\PageNotFoundException::forPageNotFound();
            }
            if (
                !($this->episode = (new EpisodeModel())
                    ->where([
                        'id' => $params[1],
                        'podcast_id' => $params[0],
                    ])
                    ->first())
            ) {
                throw \CodeIgniter\Exceptions\PageNotFoundException::forPageNotFound();
            }
        } else {
            throw \CodeIgniter\Exceptions\PageNotFoundException::forPageNotFound();
        }
        unset($params[1]);
        unset($params[0]);

        return $this->$method(...$params);
    }

    public function index()
    {
        helper('form');

        $data = [
            'episode' => $this->episode,
            'podcast' => $this->podcast,
            'episodePersons' => (new EpisodePersonModel())->getPersonsByEpisodeId(
                $this->podcast->id,
                $this->episode->id
            ),
            'personOptions' => (new PersonModel())->getPersonOptions(),
            'taxonomyOptions' => (new PersonModel())->getTaxonomyOptions(),
        ];
        replace_breadcrumb_params([
            0 => $this->podcast->title,
            1 => $this->episode->title,
        ]);
        return view('admin/episode/person', $data);
    }

    public function attemptAdd()
    {
        $rules = [
            'person' => 'required',
        ];

        if (!$this->validate($rules)) {
            return redirect()
                ->back()
                ->withInput()
                ->with('errors', $this->validator->getErrors());
        }

        (new EpisodePersonModel())->addEpisodePersons(
            $this->podcast->id,
            $this->episode->id,
            $this->request->getPost('person'),
            $this->request->getPost('person_group_role')
        );

        return redirect()->back();
    }

    public function remove($episodePersonId)
    {
        (new EpisodePersonModel())->removeEpisodePersons(
            $this->podcast->id,
            $this->episode->id,
            $episodePersonId
        );

        return redirect()->back();
    }
}
+147 −0
Original line number Diff line number Diff line
<?php

/**
 * @copyright  2021 Podlibre
 * @license    https://www.gnu.org/licenses/agpl-3.0.en.html AGPL3
 * @link       https://castopod.org/
 */

namespace App\Controllers\Admin;

use App\Models\PersonModel;

class Person extends BaseController
{
    /**
     * @var \App\Entities\Person|null
     */
    protected $person;

    public function _remap($method, ...$params)
    {
        if (count($params) > 0) {
            if (
                !($this->person = (new PersonModel())->getPersonById(
                    $params[0]
                ))
            ) {
                throw \CodeIgniter\Exceptions\PageNotFoundException::forPageNotFound();
            }
        }

        return $this->$method();
    }

    public function index()
    {
        $data = ['persons' => (new PersonModel())->findAll()];

        return view('admin/person/list', $data);
    }

    public function view()
    {
        $data = ['person' => $this->person];

        replace_breadcrumb_params([0 => $this->person->full_name]);
        return view('admin/person/view', $data);
    }

    public function create()
    {
        helper(['form']);

        return view('admin/person/create');
    }

    public function attemptCreate()
    {
        $rules = [
            'image' =>
                'is_image[image]|ext_in[image,jpg,jpeg,png]|min_dims[image,400,400]|is_image_squared[image]',
        ];

        if (!$this->validate($rules)) {
            return redirect()
                ->back()
                ->withInput()
                ->with('errors', $this->validator->getErrors());
        }

        $person = new \App\Entities\Person([
            'full_name' => $this->request->getPost('full_name'),
            'unique_name' => $this->request->getPost('unique_name'),
            'information_url' => $this->request->getPost('information_url'),
            'image' => $this->request->getFile('image'),
            'created_by' => user()->id,
            'updated_by' => user()->id,
        ]);

        $personModel = new PersonModel();

        if (!$personModel->insert($person)) {
            return redirect()
                ->back()
                ->withInput()
                ->with('errors', $personModel->errors());
        }

        return redirect()->route('person-list');
    }

    public function edit()
    {
        helper('form');

        $data = [
            'person' => $this->person,
        ];

        replace_breadcrumb_params([0 => $this->person->full_name]);
        return view('admin/person/edit', $data);
    }

    public function attemptEdit()
    {
        $rules = [
            'image' =>
                'is_image[image]|ext_in[image,jpg,jpeg,png]|min_dims[image,400,400]|is_image_squared[image]',
        ];

        if (!$this->validate($rules)) {
            return redirect()
                ->back()
                ->withInput()
                ->with('errors', $this->validator->getErrors());
        }

        $this->person->full_name = $this->request->getPost('full_name');
        $this->person->unique_name = $this->request->getPost('unique_name');
        $this->person->information_url = $this->request->getPost(
            'information_url'
        );
        $image = $this->request->getFile('image');
        if ($image->isValid()) {
            $this->person->image = $image;
        }

        $this->updated_by = user();

        $personModel = new PersonModel();
        if (!$personModel->update($this->person->id, $this->person)) {
            return redirect()
                ->back()
                ->withInput()
                ->with('errors', $personModel->errors());
        }

        return redirect()->route('person-view', [$this->person->id]);
    }

    public function delete()
    {
        (new PersonModel())->delete($this->person->id);

        return redirect()->route('person-list');
    }
}
+141 −40
Original line number Diff line number Diff line
@@ -13,6 +13,9 @@ use App\Models\LanguageModel;
use App\Models\PodcastModel;
use App\Models\EpisodeModel;
use App\Models\PlatformModel;
use App\Models\PersonModel;
use App\Models\PodcastPersonModel;
use App\Models\EpisodePersonModel;
use Config\Services;
use League\HTMLToMarkdown\HtmlConverter;

@@ -150,7 +153,7 @@ class PodcastImport extends BaseController
                    : $nsItunes->complete === 'yes',
                'location_name' => !$nsPodcast->location
                    ? null
                    : $nsPodcast->location->attributes()['name'],
                    : $nsPodcast->location,
                'location_geo' =>
                    !$nsPodcast->location ||
                    empty($nsPodcast->location->attributes()['geo'])
@@ -158,9 +161,9 @@ class PodcastImport extends BaseController
                        : $nsPodcast->location->attributes()['geo'],
                'location_osmid' =>
                    !$nsPodcast->location ||
                    empty($nsPodcast->location->attributes()['osmid'])
                    empty($nsPodcast->location->attributes()['osm'])
                        ? null
                        : $nsPodcast->location->attributes()['osmid'],
                        : $nsPodcast->location->attributes()['osm'],
                'created_by' => user(),
                'updated_by' => user(),
            ]);
@@ -200,41 +203,41 @@ class PodcastImport extends BaseController
            $podcastAdminGroup->id
        );

        $platformModel = new PlatformModel();
        $podcastsPlatformsData = [];
        foreach ($nsPodcast->id as $podcastingPlatform) {
            $slug = $podcastingPlatform->attributes()['platform'];
            $platformModel->getOrCreatePlatform($slug, 'podcasting');
            array_push($podcastsPlatformsData, [
                'platform_slug' => $slug,
                'podcast_id' => $newPodcastId,
                'link_url' => $podcastingPlatform->attributes()['url'],
                'link_content' => $podcastingPlatform->attributes()['id'],
                'is_visible' => false,
            ]);
        $platformTypes = [
            ['name' => 'podcasting', 'elements' => $nsPodcast->id],
            ['name' => 'social', 'elements' => $nsPodcast->social],
            ['name' => 'funding', 'elements' => $nsPodcast->funding],
        ];
        $platformModel = new PlatformModel();
        foreach ($platformTypes as $platformType) {
            foreach ($platformType['elements'] as $platform) {
                $platformLabel = $platform->attributes()['platform'];
                $platformSlug = slugify($platformLabel);
                if (!$platformModel->getPlatform($platformSlug)) {
                    if (
                        !$platformModel->createPlatform(
                            $platformSlug,
                            $platformType['name'],
                            $platformLabel,
                            ''
                        )
                    ) {
                        return redirect()
                            ->back()
                            ->withInput()
                            ->with('errors', $platformModel->errors());
                    }
        foreach ($nsPodcast->social as $socialPlatform) {
            $slug = $socialPlatform->attributes()['platform'];
            $platformModel->getOrCreatePlatform($slug, 'social');
            array_push($podcastsPlatformsData, [
                'platform_slug' => $socialPlatform->attributes()['platform'],
                'podcast_id' => $newPodcastId,
                'link_url' => $socialPlatform->attributes()['url'],
                'link_content' => $socialPlatform,
                'is_visible' => false,
            ]);
                }
        foreach ($nsPodcast->funding as $fundingPlatform) {
            $slug = $fundingPlatform->attributes()['platform'];
            $platformModel->getOrCreatePlatform($slug, 'funding');
                array_push($podcastsPlatformsData, [
                'platform_slug' => $fundingPlatform->attributes()['platform'],
                    'platform_slug' => $platformSlug,
                    'podcast_id' => $newPodcastId,
                'link_url' => $fundingPlatform->attributes()['url'],
                'link_content' => $fundingPlatform->attributes()['id'],
                    'link_url' => $platform->attributes()['url'],
                    'link_content' => $platform->attributes()['id'],
                    'is_visible' => false,
                ]);
            }
        }
        if (count($podcastsPlatformsData) > 1) {
            $platformModel->createPodcastPlatforms(
                $newPodcastId,
@@ -242,6 +245,54 @@ class PodcastImport extends BaseController
            );
        }

        foreach ($nsPodcast->person as $podcastPerson) {
            $personModel = new PersonModel();
            $newPersonId = null;
            if ($newPerson = $personModel->getPerson($podcastPerson)) {
                $newPersonId = $newPerson->id;
            } else {
                if (
                    !($newPersonId = $personModel->createPerson(
                        $podcastPerson,
                        $podcastPerson->attributes()['href'],
                        $podcastPerson->attributes()['img']
                    ))
                ) {
                    return redirect()
                        ->back()
                        ->withInput()
                        ->with('errors', $personModel->errors());
                }
            }

            $personGroup = empty($podcastPerson->attributes()['group'])
                ? ['slug' => '']
                : \Podlibre\PodcastNamespace\ReversedTaxonomy::$taxonomy[
                    (string) $podcastPerson->attributes()['group']
                ];
            $personRole =
                empty($podcastPerson->attributes()['role']) ||
                empty($personGroup)
                    ? ['slug' => '']
                    : $personGroup['roles'][
                        strval($podcastPerson->attributes()['role'])
                    ];
            $newPodcastPerson = new \App\Entities\PodcastPerson([
                'podcast_id' => $newPodcastId,
                'person_id' => $newPersonId,
                'person_group' => $personGroup['slug'],
                'person_role' => $personRole['slug'],
            ]);
            $podcastPersonModel = new PodcastPersonModel();

            if (!$podcastPersonModel->insert($newPodcastPerson)) {
                return redirect()
                    ->back()
                    ->withInput()
                    ->with('errors', $podcastPersonModel->errors());
            }
        }

        $numberItems = $feed->channel[0]->item->count();
        $lastItem =
            !empty($this->request->getPost('max_episodes')) &&
@@ -251,6 +302,7 @@ class PodcastImport extends BaseController

        $slugs = [];

        //////////////////////////////////////////////////////////////////
        // For each Episode:
        for ($itemNumber = 1; $itemNumber <= $lastItem; $itemNumber++) {
            $item = $feed->channel[0]->item[$numberItems - $itemNumber];
@@ -326,7 +378,7 @@ class PodcastImport extends BaseController
                    : $nsItunes->block === 'yes',
                'location_name' => !$nsPodcast->location
                    ? null
                    : $nsPodcast->location->attributes()['name'],
                    : $nsPodcast->location,
                'location_geo' =>
                    !$nsPodcast->location ||
                    empty($nsPodcast->location->attributes()['geo'])
@@ -334,9 +386,9 @@ class PodcastImport extends BaseController
                        : $nsPodcast->location->attributes()['geo'],
                'location_osmid' =>
                    !$nsPodcast->location ||
                    empty($nsPodcast->location->attributes()['osmid'])
                    empty($nsPodcast->location->attributes()['osm'])
                        ? null
                        : $nsPodcast->location->attributes()['osmid'],
                        : $nsPodcast->location->attributes()['osm'],
                'created_by' => user(),
                'updated_by' => user(),
                'published_at' => strtotime($item->pubDate),
@@ -344,13 +396,62 @@ class PodcastImport extends BaseController

            $episodeModel = new EpisodeModel();

            if (!$episodeModel->insert($newEpisode)) {
            if (!($newEpisodeId = $episodeModel->insert($newEpisode, true))) {
                // FIXME: What shall we do?
                return redirect()
                    ->back()
                    ->withInput()
                    ->with('errors', $episodeModel->errors());
            }

            foreach ($nsPodcast->person as $episodePerson) {
                $personModel = new PersonModel();
                $newPersonId = null;
                if ($newPerson = $personModel->getPerson($episodePerson)) {
                    $newPersonId = $newPerson->id;
                } else {
                    if (
                        !($newPersonId = $personModel->createPerson(
                            $episodePerson,
                            $episodePerson->attributes()['href'],
                            $episodePerson->attributes()['img']
                        ))
                    ) {
                        return redirect()
                            ->back()
                            ->withInput()
                            ->with('errors', $personModel->errors());
                    }
                }

                $personGroup = empty($episodePerson->attributes()['group'])
                    ? ['slug' => '']
                    : \Podlibre\PodcastNamespace\ReversedTaxonomy::$taxonomy[
                        strval($episodePerson->attributes()['group'])
                    ];
                $personRole =
                    empty($episodePerson->attributes()['role']) ||
                    empty($personGroup)
                        ? ['slug' => '']
                        : $personGroup['roles'][
                            strval($episodePerson->attributes()['role'])
                        ];
                $newEpisodePerson = new \App\Entities\PodcastPerson([
                    'podcast_id' => $newPodcastId,
                    'episode_id' => $newEpisodeId,
                    'person_id' => $newPersonId,
                    'person_group' => $personGroup['slug'],
                    'person_role' => $personRole['slug'],
                ]);
                $episodePersonModel = new EpisodePersonModel();

                if (!$episodePersonModel->insert($newEpisodePerson)) {
                    return redirect()
                        ->back()
                        ->withInput()
                        ->with('errors', $episodePersonModel->errors());
                }
            }
        }

        $db->transComplete();
Loading