Skip to content
Snippets Groups Projects
PersonModel.php 11.6 KiB
Newer Older
  • Learn to ignore specific revisions
  • <?php
    
    /**
     * @copyright  2021 Podlibre
     * @license    https://www.gnu.org/licenses/agpl-3.0.en.html AGPL3
     * @link       https://castopod.org/
     */
    
    namespace App\Models;
    
    
    use CodeIgniter\Database\Query;
    
    use CodeIgniter\Model;
    
    class PersonModel extends Model
    {
    
        protected $table = 'persons';
    
        protected $primaryKey = 'id';
    
    
        protected $allowedFields = [
            'id',
            'full_name',
            'unique_name',
            'information_url',
    
        protected $useSoftDeletes = false;
    
    
        protected $useTimestamps = true;
    
    
        protected $validationRules = [
            'full_name' => 'required',
            'unique_name' =>
                'required|regex_match[/^[a-z0-9\-]{1,191}$/]|is_unique[persons.unique_name,id,{id}]',
    
            'created_by' => 'required',
            'updated_by' => 'required',
        ];
    
    
        protected $afterInsert = ['clearCache'];
    
    
        /**
         * clear cache before update if by any chance, the person name changes, so will the person link
         *
         * @var string[]
         */
    
        protected $beforeUpdate = ['clearCache'];
    
        protected $beforeDelete = ['clearCache'];
    
    
        public function getPersonById(int $personId): ?Person
    
            $cacheName = "person#{$personId}";
    
            if (! ($found = cache($cacheName))) {
    
                $found = $this->find($personId);
    
                cache()
                    ->save($cacheName, $found, DECADE);
    
        public function getPerson(string $fullName): ?Person
    
            return $this->where('full_name', $fullName)
                ->first();
    
        public function getPersonRoles(int $personId, int $podcastId, ?int $episodeId): array
        {
    
            if ($episodeId) {
                $cacheName = "podcast#{$podcastId}_episode#{$episodeId}_person#{$personId}_roles";
    
    
                    $found = $this
                        ->select('episodes_persons.person_group as group, episodes_persons.person_role as role')
                        ->join('episodes_persons', 'persons.id = episodes_persons.person_id')
                        ->where('persons.id', $personId)
                        ->where('episodes_persons.episode_id', $episodeId)
                        ->get()
                        ->getResultObject();
                }
            } else {
                $cacheName = "podcast#{$podcastId}_person#{$personId}_roles";
    
    
                    $found = $this
                        ->select('podcasts_persons.person_group as group, podcasts_persons.person_role as role')
                        ->join('podcasts_persons', 'persons.id = podcasts_persons.person_id')
                        ->where('persons.id', $personId)
                        ->where('podcasts_persons.podcast_id', $podcastId)
                        ->get()
                        ->getResultObject();
                }
            }
    
            return $found;
        }
    
        /**
    
            if (! ($options = cache('person_options'))) {
    
                $options = array_reduce(
                    $this->select('`id`, `full_name`')
                        ->orderBy('`full_name`', 'ASC')
                        ->findAll(),
                    function ($result, $person) {
                        $result[$person->id] = $person->full_name;
                        return $result;
                    },
                    [],
                );
    
                cache()
                    ->save('person_options', $options, DECADE);
    
         */
        public function getTaxonomyOptions(): array
        {
            $options = [];
    
            $locale = service('request')
                ->getLocale();
    
            /** @var array<string, array<string, string|array<string, array<string, string>>>> $personsTaxonomy */
    
            if (! ($options = cache($cacheName))) {
    
                foreach ($personsTaxonomy as $group_key => $group) {
                    foreach ($group['roles'] as $role_key => $role) {
                        $options[
                            "{$group_key},{$role_key}"
                        ] = "{$group['label']}{$role['label']}";
                    }
                }
    
    
                cache()
                    ->save($cacheName, $options, DECADE);
    
        public function addPerson(string $fullName, ?string $informationUrl, string $image): int | bool
        {
    
                'full_name' => $fullName,
                'unique_name' => slugify($fullName),
                'information_url' => $informationUrl,
    
                'image' => new Image(download_file($image)),
                'created_by' => user_id(),
                'updated_by' => user_id(),
    
        /**
         * @return Person[]
         */
        public function getEpisodePersons(int $podcastId, int $episodeId): array
        {
            $cacheName = "podcast#{$podcastId}_episode#{$episodeId}_persons";
    
                $found = $this
                    ->select('persons.*, episodes_persons.podcast_id, episodes_persons.episode_id')
                    ->distinct()
                    ->join('episodes_persons', 'persons.id = episodes_persons.person_id')
                    ->where('episodes_persons.episode_id', $episodeId)
                    ->orderby('persons.full_name')
    
                cache()
                    ->save($cacheName, $found, DECADE);
    
            }
    
            return $found;
        }
    
        /**
         * @return Person[]
         */
        public function getPodcastPersons(int $podcastId): array
        {
            $cacheName = "podcast#{$podcastId}_persons";
    
                $found = $this
                    ->select('persons.*, podcasts_persons.podcast_id as podcast_id')
                    ->distinct()
                    ->join('podcasts_persons', 'persons.id=podcasts_persons.person_id')
                    ->where('podcasts_persons.podcast_id', $podcastId)
                    ->orderby('persons.full_name')
    
                cache()
                    ->save($cacheName, $found, DECADE);
    
            }
    
            return $found;
        }
    
        public function addEpisodePerson(
            int $podcastId,
            int $episodeId,
            int $personId,
    
            return $this->db->table('episodes_persons')
                ->insert([
                    'podcast_id' => $podcastId,
                    'episode_id' => $episodeId,
                    'person_id' => $personId,
                    'person_group' => $groupSlug,
                    'person_role' => $roleSlug,
                ]);
    
        }
    
        public function addPodcastPerson(
            int $podcastId,
            int $personId,
    
            return $this->db->table('podcasts_persons')
                ->insert([
                    'podcast_id' => $podcastId,
                    'person_id' => $personId,
                    'person_group' => $groupSlug,
                    'person_role' => $roleSlug,
                ]);
    
        }
    
        /**
         * Add persons to podcast
         *
         * @param array<string> $persons
    
         * @param array<string, string> $roles
    
         *
         * @return bool|int Number of rows inserted or FALSE on failure
         */
    
        public function addPodcastPersons(int $podcastId, array $persons = [], array $roles = []): int | bool
        {
    
            cache()
                ->delete("podcast#{$podcastId}_persons");
            (new PodcastModel())->clearCache([
                'id' => $podcastId,
            ]);
    
            $data = [];
            foreach ($persons as $person) {
    
                    $data[] = [
                        'podcast_id' => $podcastId,
                        'person_id' => $person,
                    ];
                }
    
    
                foreach ($roles as $role) {
                    $groupRole = explode(',', $role);
    
                    $data[] = [
                        'podcast_id' => $podcastId,
                        'person_id' => $person,
    
                        'person_group' => $groupRole[0],
                        'person_role' => $groupRole[1],
    
            return $this->db->table('podcasts_persons')
                ->insertBatch($data);
    
         * @return string|bool Number of rows inserted or FALSE on failure
    
        public function removePersonFromPodcast(int $podcastId, int $personId): string | bool
    
            return $this->db->table('podcasts_persons')
                ->delete([
                    'podcast_id' => $podcastId,
                    'person_id' => $personId,
                ]);
    
        }
    
        /**
         * Add persons to episode
         *
         * @param int[] $personIds
    
         * @return bool|int Number of rows inserted or FALSE on failure
         */
        public function addEpisodePersons(
            int $podcastId,
            int $episodeId,
            array $personIds,
    
                (new EpisodeModel())->clearCache([
                    'id' => $episodeId,
                ]);
    
    
                $data = [];
                foreach ($personIds as $personId) {
    
                    if ($groupsRoles !== []) {
                        foreach ($groupsRoles as $groupRole) {
                            $groupRole = explode(',', $groupRole);
    
                            $data[] = [
                                'podcast_id' => $podcastId,
                                'episode_id' => $episodeId,
                                'person_id' => $personId,
    
                                'person_group' => $groupRole[0],
                                'person_role' => $groupRole[1],
    
                            ];
                        }
                    } else {
                        $data[] = [
                            'podcast_id' => $podcastId,
                            'episode_id' => $episodeId,
                            'person_id' => $personId,
                        ];
                    }
                }
    
                return $this->db->table('episodes_persons')
                    ->insertBatch($data);
    
        public function removePersonFromEpisode(int $podcastId, int $episodeId, int $personId): bool | string
    
        {
            return $this->db->table('episodes_persons')
                ->delete([
                    'podcast_id' => $podcastId,
                    'episode_id' => $episodeId,
                    'person_id' => $personId,
                ]);
    
         * @return array<string, array<string|int, mixed>>
         */
        protected function clearCache(array $data): array
    
            $personId = is_array($data['id']) ? $data['id']['id'] : $data['id'];
    
            cache()
                ->delete('person_options');
            cache()
                ->delete("person#{$personId}");
    
            // clear cache for every credits page
    
            cache()
                ->deleteMatching('page_credits_*');