<?php

/*
 * This file is part of Phraseanet
 *
 * (c) 2005-2014 Alchemy
 *
 * For the full copyright and license information, please view the LICENSE
 * file that was distributed with this source code.
 */

namespace Alchemy\Phrasea\Model\Repositories;

use Alchemy\Phrasea\Model\Entities\Feed;
use Alchemy\Phrasea\Model\Entities\User;
use Doctrine\ORM\EntityRepository;

/**
 * FeedRepository
 *
 * This class was generated by the Doctrine ORM. Add your own custom
 * repository methods below.
 */
class FeedRepository extends EntityRepository
{
    /**
     * Returns all the feeds a user can access.
     *
     * @param \ACL  $userACL
     * @param array $restrictions
     *
     * @return Feed[]
     */
    public function getAllForUser(\ACL $userACL, array $restrictions = [])
    {
        $base_ids = array_keys($userACL->get_granted_base());

        $qb = $this
            ->createQueryBuilder('f');

        $qb->where($qb->expr()->isNull('f.baseId'))
            ->orWhere($qb->expr()->eq('f.public', $qb->expr()->literal(true)));

        if (count($restrictions) > 0 && count($base_ids) > 0) {
            $base_ids = array_intersect($base_ids, $restrictions);
        }

        if (empty($base_ids) && count($restrictions) > 0) {
            $base_ids = $restrictions;
        }

        if (count($base_ids) > 0) {
            $qb->orWhere($qb->expr()->in('f.baseId', $base_ids));
        }

        $qb->orderBy('f.updatedOn', 'DESC');

        return $qb->getQuery()->getResult();
    }

    /**
     * Returns all the feeds from a given array containing their id.
     *
     * @param  array      $feedIds
     * @return Feed[]
     */
    public function findByIds(array $feedIds)
    {
        $qb = $this->createQueryBuilder('f');

        if (!empty($feedIds)) {
            $qb->Where($qb->expr()->in('f.id', $feedIds));
        }

        $qb->orderBy('f.updatedOn', 'DESC');

        return $qb->getQuery()->getResult();
    }

    /**
     * Returns all the feeds from a given array containing their id.
     *
     * @param \ACL   $userACL
     * @param  array $feedIds Ids to restrict feeds, all accessible otherwise
     *
     * @return Feed[]
     */
    public function filterUserAccessibleByIds(\ACL $userACL, array $feedIds = [])
    {
        $qb = $this->createQueryBuilder('f');

        // is public feed?
        $orx = $qb->expr()->orX(
            $qb->expr()->isNull('f.baseId'),
            $qb->expr()->eq('f.public', $qb->expr()->literal(true))
        );

        // is granted base?
        $grantedBases = array_keys($userACL->get_granted_base());
        if ($grantedBases) {
            $orx->add($qb->expr()->in('f.baseId', $grantedBases));
        }

        if ($feedIds) {
            $qb->where($qb->expr()->in('f.id', $feedIds), $orx);
        }

        $qb->orderBy('f.updatedOn', 'DESC');

        return $qb->getQuery()->getResult();
    }

    public function getUserFeed(User $user)
    {
        $qb = $this->createQueryBuilder('f');
        $qb->innerJoin('f.publishers', 'fp');
        $qb->where($qb->expr()->eq('fp.user', ':publisher'));
        $qb->setParameter(':publisher', $user);

        return $qb->getQuery()->getResult();
    }
}
