<commit_before><?php

namespace Drivegal;

use Drivegal\Exception\AlbumNotFoundException;
use Drivegal\Exception\ServiceAuthException;
use Drivegal\Exception\ServiceException;
use Google_Exception;
use Google_Auth_Exception;
use Google_Service_Drive;
use Google_Service_Drive_DriveFile;
use Cocur\Slugify\Slugify;
use Drivegal\GalleryFile\AbstractFile as GalleryFile;
use Drivegal\GalleryFile\Album;
use Drivegal\GalleryFile\Image;
use Drivegal\GalleryFile\Movie;
use \DateTime;
use Doctrine\Common\Cache\Cache;

class GalleryService
{
    /** @var GalleryInfoMapper */
    protected $galleryInfoMapper;

    /** @var Authenticator */
    protected $authenticator;

    /** @var Slugify */
    protected $slugify;

    /** @var Cache */
    protected $cache;

    protected $cacheTtl = 900;

    /**
     * @param Authenticator $authenticator
     * @param GalleryInfoMapper $galleryInfoMapper
     * @param Slugify $slugify
     * @param Cache $cache
     */
    public function __construct(Authenticator $authenticator, GalleryInfoMapper $galleryInfoMapper, Slugify $slugify, Cache $cache)
    {
        $this->authenticator = $authenticator;
        $this->galleryInfoMapper = $galleryInfoMapper;
        $this->slugify = $slugify;
        $this->cache = $cache;
    }

    /**
     * @param GalleryInfo $galleryInfo
     * @return GalleryInfo
     */
    public function saveGalleryInfo(GalleryInfo $galleryInfo)
    {
        return $this->galleryInfoMapper->save($galleryInfo);
    }

    /**
     * @param int $id
     * @return GalleryInfo|null
     */
    public function findGalleryInfoByGoogleUserId($id)
    {
        return $this->galleryInfoMapper->findByGoogleUserId($id);
    }

    /**
     * @param string $slug
     * @return GalleryInfo|null
     */
    public function findGalleryInfoBySlug($slug)
    {
        return $this->galleryInfoMapper->findBySlug($slug);
    }

    /**
     * @param GalleryInfo $galleryInfo
     * @param string $albumPath
     * @return AlbumContents
     * @throws Exception\ServiceException
     * @throws Exception\AlbumNotFoundException
     * @throws Exception\ServiceAuthException
     */
    public function getAlbumContents(GalleryInfo $galleryInfo, $albumPath)
    {
        $files = $album = null;

        try {
            $driveService = $this->createDriveService($galleryInfo);
            $albumIndex = $this->fetchAlbumIndex($driveService);

            if ($albumPath) {
                $album = $albumIndex->findByPath($albumPath);
                if (!$album) {
                    throw new AlbumNotFoundException();
                }

                $files = $this->fetchGalleryFiles($driveService, array('album' => $album));

                // Order files in reverse chronological order.
                uasort($files, function(GalleryFile $a, GalleryFile $b) {
                    return strcmp($b->getDate(), $a->getDate());
                });
            }

        } catch (Google_Auth_Exception $e) {
            throw new ServiceAuthException($e->getMessage(), $e->getCode(), $e);
        } catch (Google_Exception $e) {
            if ($e->getCode() == 401) {
                throw new ServiceAuthException($e->getMessage(), $e->getCode(), $e);
            } else {
                throw new ServiceException($e->getMessage(), $e->getCode(), $e);
            }
        }

        // Create AlbumContents object and return it.
        $albumContents = new AlbumContents();
        $albumContents->setTitle($album ? $album->getTitle() : $galleryInfo->getGalleryName());
        $albumContents->setSubAlbums($albumIndex->getSubAlbums($album));
        if ($files) {
            $albumContents->setFiles($files);
        }
        if ($album) {
            $albumContents->setBreadcrumbs($this->getBreadcrumbs($albumPath, $galleryInfo, $albumIndex));
        }

        return $albumContents;
    }

    /**
     * @param string $albumPath
     * @param GalleryInfo $galleryInfo
     * @param AlbumIndex $albumIndex
     * @return array An array of breadcrumbs, in the format array(relativePath => $title, ...).
     *         The current album (the last one in $albumPath) is not included.
     */
    protected function getBreadcrumbs($albumPath, GalleryInfo $galleryInfo, AlbumIndex $albumIndex)
    {
        $breadcrumbs = array();

        $path = $galleryInfo->getSlug() . '/album/';
        // $breadcrumbs[$path] = $galleryInfo->getGalleryName();
        $breadcrumbs[$path] = 'Albums';

        $albumSlugs = explode('/', $albumPath);
        array_pop($albumSlugs); // The last one in the path is the current page, not part of the breadcrumb trail.

        $partialAlbumPath = '';
        foreach ($albumSlugs as $albumSlug) {
            $partialAlbumPath .= $albumSlug . '/';
            $path .= $partialAlbumPath;

            $album = $albumIndex->findByPath($partialAlbumPath);
            if ($album) {
                $breadcrumbs[$path] = $album->getTitle();
            }
        }<commit_msg>Fix bug generating breadcrumbs for long paths.<commit_after><?php

namespace Drivegal;

use Drivegal\Exception\AlbumNotFoundException;
use Drivegal\Exception\ServiceAuthException;
use Drivegal\Exception\ServiceException;
use Google_Exception;
use Google_Auth_Exception;
use Google_Service_Drive;
use Google_Service_Drive_DriveFile;
use Cocur\Slugify\Slugify;
use Drivegal\GalleryFile\AbstractFile as GalleryFile;
use Drivegal\GalleryFile\Album;
use Drivegal\GalleryFile\Image;
use Drivegal\GalleryFile\Movie;
use \DateTime;
use Doctrine\Common\Cache\Cache;

class GalleryService
{
    /** @var GalleryInfoMapper */
    protected $galleryInfoMapper;

    /** @var Authenticator */
    protected $authenticator;

    /** @var Slugify */
    protected $slugify;

    /** @var Cache */
    protected $cache;

    protected $cacheTtl = 900;

    /**
     * @param Authenticator $authenticator
     * @param GalleryInfoMapper $galleryInfoMapper
     * @param Slugify $slugify
     * @param Cache $cache
     */
    public function __construct(Authenticator $authenticator, GalleryInfoMapper $galleryInfoMapper, Slugify $slugify, Cache $cache)
    {
        $this->authenticator = $authenticator;
        $this->galleryInfoMapper = $galleryInfoMapper;
        $this->slugify = $slugify;
        $this->cache = $cache;
    }

    /**
     * @param GalleryInfo $galleryInfo
     * @return GalleryInfo
     */
    public function saveGalleryInfo(GalleryInfo $galleryInfo)
    {
        return $this->galleryInfoMapper->save($galleryInfo);
    }

    /**
     * @param int $id
     * @return GalleryInfo|null
     */
    public function findGalleryInfoByGoogleUserId($id)
    {
        return $this->galleryInfoMapper->findByGoogleUserId($id);
    }

    /**
     * @param string $slug
     * @return GalleryInfo|null
     */
    public function findGalleryInfoBySlug($slug)
    {
        return $this->galleryInfoMapper->findBySlug($slug);
    }

    /**
     * @param GalleryInfo $galleryInfo
     * @param string $albumPath
     * @return AlbumContents
     * @throws Exception\ServiceException
     * @throws Exception\AlbumNotFoundException
     * @throws Exception\ServiceAuthException
     */
    public function getAlbumContents(GalleryInfo $galleryInfo, $albumPath)
    {
        $files = $album = null;

        try {
            $driveService = $this->createDriveService($galleryInfo);
            $albumIndex = $this->fetchAlbumIndex($driveService);

            if ($albumPath) {
                $album = $albumIndex->findByPath($albumPath);
                if (!$album) {
                    throw new AlbumNotFoundException();
                }

                $files = $this->fetchGalleryFiles($driveService, array('album' => $album));

                // Order files in reverse chronological order.
                uasort($files, function(GalleryFile $a, GalleryFile $b) {
                    return strcmp($b->getDate(), $a->getDate());
                });
            }

        } catch (Google_Auth_Exception $e) {
            throw new ServiceAuthException($e->getMessage(), $e->getCode(), $e);
        } catch (Google_Exception $e) {
            if ($e->getCode() == 401) {
                throw new ServiceAuthException($e->getMessage(), $e->getCode(), $e);
            } else {
                throw new ServiceException($e->getMessage(), $e->getCode(), $e);
            }
        }

        // Create AlbumContents object and return it.
        $albumContents = new AlbumContents();
        $albumContents->setTitle($album ? $album->getTitle() : $galleryInfo->getGalleryName());
        $albumContents->setSubAlbums($albumIndex->getSubAlbums($album));
        if ($files) {
            $albumContents->setFiles($files);
        }
        if ($album) {
            $albumContents->setBreadcrumbs($this->getBreadcrumbs($albumPath, $galleryInfo, $albumIndex));
        }

        return $albumContents;
    }

    /**
     * @param string $albumPath
     * @param GalleryInfo $galleryInfo
     * @param AlbumIndex $albumIndex
     * @return array An array of breadcrumbs, in the format array(relativePath => $title, ...).
     *         The current album (the last one in $albumPath) is not included.
     */
    protected function getBreadcrumbs($albumPath, GalleryInfo $galleryInfo, AlbumIndex $albumIndex)
    {
        $breadcrumbs = array();

        $path = $galleryInfo->getSlug() . '/album/';
        $breadcrumbs[$path] = 'Albums';

        $albumSlugs = explode('/', $albumPath);
        array_pop($albumSlugs); // The last one in the path is the current page, not part of the breadcrumb trail.

        $partialAlbumPath = '';
        foreach ($albumSlugs as $albumSlug) {
            $partialAlbumPath .= $albumSlug . '/';
            $path .= basename($partialAlbumPath) . '/';

            $album = $albumIndex->findByPath($partialAlbumPath);
            if ($album) {
                $breadcrumbs[$path] = $album->getTitle();
            }
        }
{'fraction_non_alphanumeric': 0.12319422150882825, 'fraction_numerical': 0.001203852327447833, 'mean_word_length': 2.494216614090431, 'pattern_counts': {'":': 0, '<': 5, '<?xml version=': 0, '>': 76, 'https://': 0, 'lorem ipsum': 0, 'www.': 0, 'xml': 0}, 'pii_count': 0, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 0, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'dir': 'git-commits-cleaned', 'id': '4716125', 'n_tokens_mistral': 2881, 'n_tokens_neox': 2764, 'n_words': 602}