<commit_before><?php
namespace Entity;

use \Doctrine\Common\Collections\ArrayCollection;

/**
 * @Table(name="podcast")
 * @Entity
 */
class Podcast extends \DF\Doctrine\Entity
{
    public function __construct()
    {
        $this->episodes = new ArrayCollection;
        $this->stations = new ArrayCollection;
    }

    /**
     * @Column(name="id", type="integer")
     * @Id
     * @GeneratedValue(strategy="IDENTITY")
     */
    protected $id;

    /** @Column(name="name", type="string", length=150, nullable=true) */
    protected $name;

    /** @Column(name="country", type="string", length=50, nullable=true) */
    protected $country;

    public function getCountryName()
    {
        if ($this->country)
            return \PVL\Internationalization::getLanguageName($this->country);
        else
            return '';
    }

    /** @Column(name="description", type="text", nullable=true) */
    protected $description;

    /** @Column(name="image_url", type="string", length=100, nullable=true) */
    protected $image_url;

    public function setImageUrl($new_url)
    {
        if ($new_url)
        {
            if ($this->image_url && $this->image_url != $new_url)
                @unlink(DF_UPLOAD_FOLDER.DIRECTORY_SEPARATOR.$this->image_url);

            $new_path = DF_UPLOAD_FOLDER.DIRECTORY_SEPARATOR.$new_url;
            \DF\Image::resizeImage($new_path, $new_path, 150, 150);

            $this->image_url = $new_url;
        }
    }

    public function getImageUrl()
    {
        return self::getArtistImage($this->image_url);
    }

    /** @Column(name="web_url", type="string", length=255, nullable=true) */
    protected $web_url;

    /** @Column(name="twitter_url", type="string", length=255, nullable=true) */
    protected $twitter_url;

    /** @Column(name="rss_url", type="string", length=255, nullable=true) */
    protected $rss_url;

    /** @Column(name="tumblr_url", type="string", length=255, nullable=true) */
    protected $tumblr_url;

    /** @Column(name="facebook_url", type="string", length=255, nullable=true) */
    protected $facebook_url;

    /** @Column(name="youtube_url", type="string", length=255, nullable=true) */
    protected $youtube_url;

    /** @Column(name="soundcloud_url", type="string", length=255, nullable=true) */
    protected $soundcloud_url;

    /** @Column(name="deviantart_url", type="string", length=255, nullable=true) */
    protected $deviantart_url;

    /** @Column(name="livestream_url", type="string", length=255, nullable=true) */
    protected $livestream_url;

    /** @Column(name="sync_timestamp", type="datetime", nullable=true) */
    protected $sync_timestamp;

    /** @Column(name="is_approved", type="boolean") */
    protected $is_approved;

    /**
     * @OnetoMany(targetEntity="PodcastEpisode", mappedBy="podcast")
     * @OrderBy({"timestamp" = "DESC"})
     */
    protected $episodes;

    /**
     * @ManyToMany(targetEntity="Station")
     * @JoinTable(name="podcast_on_station",
     *      joinColumns={@JoinColumn(name="podcast_id", referencedColumnName="id", onDelete="CASCADE")},
     *      inverseJoinColumns={@JoinColumn(name="station_id", referencedColumnName="id", onDelete="CASCADE")}
     * )
     */
    protected $stations;

    /**
     * Static Functions
     */

    public static function fetchLatest($num_to_fetch = 10)
    {
        $em = self::getEntityManager();

        // $podcasts = \DF\Cache::get('homepage_podcasts');

        if (!$podcasts)
        {
            $latest_podcast_episodes = $em->createQuery('SELECT pe, MAX(pe.timestamp) FROM Entity\PodcastEpisode pe WHERE pe.timestamp > :threshold GROUP BY pe.podcast_id ORDER BY pe.timestamp DESC')
                ->setMaxResults($num_to_fetch)
                ->setParameter('threshold', strtotime('-3 months'))
                ->getArrayResult();

            $eps = array();
            foreach($latest_podcast_episodes as $ep)
            {
                $eps[$ep[0]['podcast_id']] = $ep[0];
            }

            $podcasts_raw = $em->createQuery('SELECT p, s FROM Entity\Podcast p JOIN p.stations s WHERE p.id IN (:podcasts)')
                ->setParameter('podcasts', array_keys($eps))
                ->getArrayResult();

            $podcasts = array();
            foreach($podcasts_raw as $pc)
            {
                $ep = $eps[$pc['id']];
                $pc['timestamp'] = $ep['timestamp'];

                $podcasts[$pc['id']] = $pc;
                $podcasts[$pc['id']]['episodes'] = array($ep);
            }

            \PVL\Utilities::orderBy($podcasts, 'timestamp DESC');

            \DF\Cache::save($podcasts, 'homepage_podcasts', array(), 300);
        }

        return $podcasts;
    }

    public static function api($row_obj, $include_episodes = TRUE)
    {
        if ($row_obj instanceof self)
        {
            $row = $row_obj->toArray();

            $row['stations'] = array();
            if ($row_obj->stations)
            {<commit_msg>Reworking podcast query *again*.<commit_after><?php
namespace Entity;

use \Doctrine\Common\Collections\ArrayCollection;

/**
 * @Table(name="podcast")
 * @Entity
 */
class Podcast extends \DF\Doctrine\Entity
{
    public function __construct()
    {
        $this->episodes = new ArrayCollection;
        $this->stations = new ArrayCollection;
    }

    /**
     * @Column(name="id", type="integer")
     * @Id
     * @GeneratedValue(strategy="IDENTITY")
     */
    protected $id;

    /** @Column(name="name", type="string", length=150, nullable=true) */
    protected $name;

    /** @Column(name="country", type="string", length=50, nullable=true) */
    protected $country;

    public function getCountryName()
    {
        if ($this->country)
            return \PVL\Internationalization::getLanguageName($this->country);
        else
            return '';
    }

    /** @Column(name="description", type="text", nullable=true) */
    protected $description;

    /** @Column(name="image_url", type="string", length=100, nullable=true) */
    protected $image_url;

    public function setImageUrl($new_url)
    {
        if ($new_url)
        {
            if ($this->image_url && $this->image_url != $new_url)
                @unlink(DF_UPLOAD_FOLDER.DIRECTORY_SEPARATOR.$this->image_url);

            $new_path = DF_UPLOAD_FOLDER.DIRECTORY_SEPARATOR.$new_url;
            \DF\Image::resizeImage($new_path, $new_path, 150, 150);

            $this->image_url = $new_url;
        }
    }

    public function getImageUrl()
    {
        return self::getArtistImage($this->image_url);
    }

    /** @Column(name="web_url", type="string", length=255, nullable=true) */
    protected $web_url;

    /** @Column(name="twitter_url", type="string", length=255, nullable=true) */
    protected $twitter_url;

    /** @Column(name="rss_url", type="string", length=255, nullable=true) */
    protected $rss_url;

    /** @Column(name="tumblr_url", type="string", length=255, nullable=true) */
    protected $tumblr_url;

    /** @Column(name="facebook_url", type="string", length=255, nullable=true) */
    protected $facebook_url;

    /** @Column(name="youtube_url", type="string", length=255, nullable=true) */
    protected $youtube_url;

    /** @Column(name="soundcloud_url", type="string", length=255, nullable=true) */
    protected $soundcloud_url;

    /** @Column(name="deviantart_url", type="string", length=255, nullable=true) */
    protected $deviantart_url;

    /** @Column(name="livestream_url", type="string", length=255, nullable=true) */
    protected $livestream_url;

    /** @Column(name="sync_timestamp", type="datetime", nullable=true) */
    protected $sync_timestamp;

    /** @Column(name="is_approved", type="boolean") */
    protected $is_approved;

    /**
     * @OnetoMany(targetEntity="PodcastEpisode", mappedBy="podcast")
     * @OrderBy({"timestamp" = "DESC"})
     */
    protected $episodes;

    /**
     * @ManyToMany(targetEntity="Station")
     * @JoinTable(name="podcast_on_station",
     *      joinColumns={@JoinColumn(name="podcast_id", referencedColumnName="id", onDelete="CASCADE")},
     *      inverseJoinColumns={@JoinColumn(name="station_id", referencedColumnName="id", onDelete="CASCADE")}
     * )
     */
    protected $stations;

    /**
     * Static Functions
     */

    public static function fetchLatest($num_to_fetch = 10)
    {
        $em = self::getEntityManager();

        $podcasts = \DF\Cache::get('homepage_podcasts');

        if (!$podcasts)
        {
            // Pull all recent episodes.
            $latest_podcast_episodes = $em->createQuery('SELECT pe FROM Entity\PodcastEpisode pe WHERE pe.timestamp > :threshold ORDER BY pe.timestamp DESC')
                ->setParameter('threshold', strtotime('-3 months'))
                ->getArrayResult();

            $eps = array();
            foreach($latest_podcast_episodes as $ep)
            {
                $pcid = $ep['podcast_id'];

                if (!isset($eps[$pcid]))
                    $eps[$pcid] = $ep;
            }

            // Bulk query for all podcasts related to recent episodes.
            $podcasts_raw = $em->createQuery('SELECT p, s FROM Entity\Podcast p JOIN p.stations s WHERE p.id IN (:podcasts)')
                ->setParameter('podcasts', array_keys($eps))
                ->getArrayResult();

            foreach($podcasts_raw as $pc)
                $eps[$pc['id']]['podcast'] = $pc;

            // Reassign together into sensible array.
            $podcasts = array();
            foreach($eps as $ep)
            {
                $pc = $ep['podcast'];
                unset($ep['podcast']);
                $pc['episodes'] = array($ep);

                $podcasts[$pc['id']] = $pc;
            }

            array_slice($podcasts, 0, $num_to_fetch, true);

            \DF\Cache::save($podcasts, 'homepage_podcasts', array(), 300);
        }

        return $podcasts;
    }

    public static function api($row_obj, $include_episodes = TRUE)
    {
        if ($row_obj instanceof self)
        {
            $row = $row_obj->toArray();

            $row['stations'] = array();
            if ($row_obj->stations)
            {
{'fraction_non_alphanumeric': 0.161078431372549, 'fraction_numerical': 0.009509803921568628, 'mean_word_length': 2.6020480225988702, 'pattern_counts': {'":': 0, '<': 5, '<?xml version=': 0, '>': 40, 'https://': 0, 'lorem ipsum': 0, 'www.': 0, 'xml': 0}, 'pii_count': 0, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 4, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'dir': 'git-commits-cleaned', 'id': '7562233', 'n_tokens_mistral': 3302, 'n_tokens_neox': 3080, 'n_words': 539}