<?php

/**
 * @copyright (C) 2013 iJoomla, Inc. - All rights reserved.
 * @license GNU General Public License, version 2 (http://www.gnu.org/licenses/gpl-2.0.html)
 * @author iJoomla.com <webmaster@ijoomla.com>
 * @url https://www.jomsocial.com/license-agreement
 * The PHP code portions are distributed under the GPL license. If not otherwise stated, all images, manuals, cascading style sheets, and included JavaScript *are NOT GPL, and are released under the IJOOMLA Proprietary Use License v1.0
 * More info at https://www.jomsocial.com/license-agreement
 */

use Joomla\CMS\Factory;
use Joomla\CMS\Language\Text;
use Joomla\CMS\Pagination\Pagination;
use Joomla\CMS\Table\Table;
use Joomla\Filesystem\File;
use Joomla\Filesystem\Path;

// no direct access
defined('_JEXEC') or die('Restricted access');

require_once ( JPATH_ROOT . '/components/com_community/models/models.php');

class CommunityModelVideos extends JCCModel implements CLimitsInterface {

    var $_pagination = '';
    var $total = '';

    public function __construct() {
        parent::__construct();

        $mainframe = Factory::getApplication();
        $jinput = $mainframe->input;
        $id = $jinput->get('videoid', 0, 'int');
        $this->setId((int) $id);

        $config = CFactory::getConfig();
        // Get the pagination request variables
        $limit = $config->get('pagination');
        $limitstart = $jinput->request->get('limitstart', 0, 'INT');

        if (empty($limitstart)) {
            $limitstart = $jinput->get('limitstart', 0, 'uint');
        }

        // In case limit has been changed, adjust limitstart accordingly
        $limitstart = ($limit != 0 ? (floor($limitstart / $limit) * $limit) : 0);

        $this->setState('limit', $limit);
        $this->setState('limitstart', $limitstart);
    }

    public function setId($id) {
        // Set new video ID and wipe data
        $this->_id = $id;
        return $this;
    }

    /**
     * 	Checks whether specific user or group has pending videos
     *
     * 	@params	$id	int	The unique id of the creator or groupid
     * 	@params	$type	string	The video type whether user or group
     * */
    public function hasPendingVideos($id, $type = VIDEO_USER_TYPE) {
        if ($type == VIDEO_USER_TYPE && $id == 0) {
            return 0;
        }

        $db = $this->getDBO();

        $query = 'SELECT COUNT(*) FROM ' . $db->quoteName('#__community_videos') . ' '
                . 'WHERE ' . $db->quoteName('creator_type') . '=' . $db->Quote($type) . ' ';

        if ($type == VIDEO_USER_TYPE) {
            $query .= 'AND ' . $db->quoteName('creator') . '=' . $db->Quote($id);
        }elseif($type == VIDEO_EVENT_TYPE){
            $query .= 'AND ' . $db->quoteName('eventid') . '=' . $db->Quote($id);
        } else {
            $query .= 'AND ' . $db->quoteName('groupid') . '=' . $db->Quote($id);
        }

        $query .= ' AND ' . $db->quoteName('status') . '=' . $db->Quote('pending');
        $query .= ' AND ' . $db->quoteName('published') . '=' . $db->Quote(1);

        $db->setQuery($query);
        $result = $db->loadResult() >= 1 ? true : false;

        return $result;
    }

    /**
     * Loads the videos
     *
     * @public
     * @param	array	$filters	The video's filter
     * @return	array	An array of videos object
     * @since	1.2
     */
    public function getVideos($filters = array(), $tableBind = false, $limitSetting = true, $useCache = true, $pagination = true) {
        $jinput = Factory::getApplication()->input;
        /* use caching */
        if ($useCache) {
            $cache = CFactory::getFastCache();
            $cacheid = serialize(func_get_args()) . serialize($jinput->getArray());
            if ($data = $cache->get($cacheid)) {
                jimport('joomla.html.pagination');
                $this->_pagination = new JPagination($data['total'], $data['limitstart'], $data['limit']);
                return $data['entries'];
            }
        }

        $db = $this->getDBO();

        $my = CFactory::getUser();

        $where = array();
        $limiter = '';
        $defaultFilters = array(
            'published' => 1
        );
        $filters = array_merge($defaultFilters,$filters);
        foreach ($filters as $field => $value) {
            if ($value || $value === 0) {
                switch (strtolower($field)) {
                    case 'id':
                        if (is_array($value)) {
                            $value = Joomla\Utilities\ArrayHelper::toInteger($value);
                            $value = implode(',', $value);
                        }
                        $where[] = 'v.' . $db->quoteName('id') . ' IN (' . $value . ')';
                        break;
                    case 'title':
                        $where[] = 'v.' . $db->quoteName('title') . '  LIKE ' . $db->quote('%' . $value . '%');
                        break;
                    case 'type':
                        $where[] = 'v.' . $db->quoteName('type') . ' = ' . $db->quote($value);
                        break;
                    case 'description':
                        $where[] = 'v.' . $db->quoteName('description') . ' LIKE ' . $db->quote('%' . $value . '%');
                        break;
                    case 'creator':
                        $where[] = 'v.' . $db->quoteName('creator') . ' = ' . $db->quote((int) $value);
                        break;
                    case 'creator_type':
                        $where[] = 'v.' . $db->quoteName('creator_type') . ' = ' . $db->quote($value);
                        break;
                    case 'created':
                        $value = JDate::getInstance($value)->toSql();
                        $where[] = 'v.' . $db->quoteName('created') . ' BETWEEN ' . $db->quote('1970-01-01 00:00:01') . ' AND ' . $db->quote($value);
                        break;
                    case 'permissions':
                        if (isset($filters['friendsvideos']) && $filters['friendsvideos']) {
                            $extrasql = '';
                            if ($my->id != 0) {
                                if (empty($filters['groupid'])) {
                                    $friendmodel = CFactory::getModel('friends');
                                    $friends = $friendmodel->getFriendIds($my->id);
                                    if (!empty($friends)) {
                                        $extrasql .= ' OR (v.creator IN(' . implode(',', $friends) . ') AND v.permissions = ' . $db->Quote(30) . ') ';
                                    }
                                }
                            }
                            $where[] = '( v.' . $db->quoteName('permissions') . ' <= ' . $db->quote((int) $value) . ' ' . $extrasql . '  OR ( v.creator=' . $db->Quote($my->id) . ' AND v.permissions <=' . $db->Quote(40) . ' ) )';
                        } else {
                            $where[] = 'v.' . $db->quoteName('permissions') . ' <= ' . $db->quote((int) $value);
                        }

                        break;
                    case 'category_id':
                        if (is_array($value)) {
                            $value = Joomla\Utilities\ArrayHelper::toInteger($value);
                            $value = implode(',', $value);
                        }
                        if($value!=0) $where[] = 'v.' . $db->quoteName('category_id') . ' IN (' . $value . ')';
                        break;
                    case 'hits':
                        $where[] = 'v.' . $db->quoteName('hits') . ' >= ' . $db->quote((int) $value);
                        break;
                    case 'published':
                        $where[] = 'v.' . $db->quoteName('published') . ' = ' . $db->quote((bool) $value);
                        break;
                    case 'featured':
                        $where[] = 'v.' . $db->quoteName('featured') . ' = ' . $db->quote((bool) $value);
                        break;
                    case 'duration':
                        $where[] = 'v.' . $db->quoteName('duration') . ' >= ' . $db->quote((int) $value);
                        break;
                    case 'status':
                        $where[] = 'v.' . $db->quoteName('status') . ' = ' . $db->quote($value);
                        break;
                    case 'pageid':
                        $where[] = 'v.' . $db->quoteName('pageid') . ' = ' . $db->quote($value);
                        break;
                    case 'groupid':
                        $where[] = 'v.' . $db->quoteName('groupid') . ' = ' . $db->quote($value);
                        break;
                    case 'eventid':
                        $where[] = 'v.' . $db->quoteName('eventid') . ' = ' . $db->quote($value);
                        break;
                    case 'pagesonly':
                        $where[] = 'v.' . $db->quoteName('pageid') . ' > ' . $db->quote(0);
                        break;
                    case 'groupsonly':
                        $where[] = 'v.' . $db->quoteName('groupid') . ' > ' . $db->quote(0);
                        break;
                    case 'eventsonly':
                        $where[] = 'v.' . $db->quoteName('eventid') . ' > ' . $db->quote(0);
                        break;
                    case 'limitstart':
                        $limitstart = (int) $value;
                        break;
                    case 'limit':
                        $limit = (int) $value;
                        break;
                }
            }
        }

        $where = count($where) ? ' WHERE ' . implode(' AND ', $where) : '';

        // hide blocked user videos
        if ($my->id > 0 && !COwnerHelper::isCommunityAdmin()) {
            $blockLists = $my->getBlockedUsers();
            $blockedUserIds = array();
            foreach ($blockLists as $blocklist) {
                $blockedUserIds[] = $blocklist->blocked_userid;
            }

            $blockedUserIds = implode(",", $blockedUserIds);

            if ($blockedUserIds) {
                $where .= ' AND v.'.$db->quoteName('creator').' NOT IN (' . $blockedUserIds . ') ';
            }
        }

        // Joint with group table
        $join = '';
        if (isset($filters['or_group_privacy']) && !COwnerHelper::isCommunityAdmin()) {
            $approvals = (int) $filters['or_group_privacy'];
            $join .= ' LEFT JOIN ' . $db->quoteName('#__community_groups') . ' AS g';
            $join .= ' ON g.' . $db->quoteName('id') . ' = v.' . $db->quoteName('groupid');
            $join .= ' LEFT JOIN ' . $db->quoteName('#__community_groups_members') . ' AS gm';
            $join .= ' ON gm.' . $db->quoteName('groupid') . ' = g.' . $db->quoteName('id');
            
            $where .= ' AND ((g.' . $db->quoteName('approvals') . ' = ' . $db->Quote('0') . ' OR g.' . $db->quoteName('approvals') . ' IS NULL)';
            $where .= ' OR (g.' . $db->quoteName('approvals') . ' = ' . $db->Quote('1') . ' AND (g.' . $db->quoteName('ownerid') . '=' . $db->Quote($my->id) . ' OR (gm.' . $db->quoteName('memberid') . '=' . $db->Quote($my->id) . ' AND gm.' . $db->quoteName('approved') . '=' . $db->Quote('1') . '))))';
        }

        if (isset($filters['or_page_privacy']) && !COwnerHelper::isCommunityAdmin()) {
            $approvals = (int) $filters['or_page_privacy'];
            $join .= ' LEFT JOIN ' . $db->quoteName('#__community_pages') . ' AS p';
            $join .= ' ON p.' . $db->quoteName('id') . ' = v.' . $db->quoteName('pageid');
            $join .= ' LEFT JOIN ' . $db->quoteName('#__community_pages_members') . ' AS pm';
            $join .= ' ON pm.' . $db->quoteName('pageid') . ' = p.' . $db->quoteName('id');
            
            $where .= ' AND ((p.' . $db->quoteName('approvals') . ' = ' . $db->Quote('0') . ' OR p.' . $db->quoteName('approvals') . ' IS NULL)';
            $where .= ' OR (p.' . $db->quoteName('approvals') . ' = ' . $db->Quote('1') . ' AND (p.' . $db->quoteName('ownerid') . '=' . $db->Quote($my->id) . ' OR (pm.' . $db->quoteName('memberid') . '=' . $db->Quote($my->id) . ' AND pm.' . $db->quoteName('approved') . '=' . $db->Quote('1') . '))))';
        }
        
        $config = CFactory::getConfig();
        if (!$config->get('enablepages')) {
            $where .= ' AND v.' . $db->quoteName('creator_type') . '!=' . $db->Quote(VIDEO_PAGE_TYPE);
        }

        if (!$config->get('enablegroups')) {
            $where .= ' AND v.' . $db->quoteName('creator_type') . '!=' . $db->Quote(VIDEO_GROUP_TYPE);
        }

        if (!$config->get('enableevents')) {
            $where .= ' AND v.' . $db->quoteName('creator_type') . '!=' . $db->Quote(VIDEO_EVENT_TYPE);
        }

        $limit = (isset($limit)) ? $limit : $this->getState('limit');
        $limit = ($limit < 0) ? 0 : $limit;
        if($pagination){
            $limitstart = (isset($limitstart)) ? $limitstart : $this->getState('limitstart');
        }else{
            $limitstart = 0;
        }


        if ($limitSetting == true) {
            /* Temporary fix for ajaxGetFeaturedVideos LIMIT 0,0 */
            if ($limit != 0)
                $limiter = ' LIMIT ' . $limitstart . ', ' . $limit;
        } else {
            $limiter = '';
        }

        $order = '';
        $sorting = isset($filters['sorting']) ? $filters['sorting'] : 'latest';

        switch ($sorting) {
            case 'mostwalls':

                // do a query to get the most commented items ids
                $wallquery = ' SELECT contentid'
                        . ' FROM ' . $db->quoteName('#__community_wall')
                        . ' WHERE ' . $db->quoteName('type') . ' = ' . $db->quote('videos')
                        . ' AND ' . $db->quoteName('published') . ' = ' . $db->quote(1)
                        . ' group by id '
                        . ' order by count(*) DESC ';

                $db->setQuery($wallquery);
                $wallResult = $db->loadColumn();
                $sortedResult = array();

                // key represents content id, and value is the total comment that exists
                foreach($wallResult as $result){
                    if(!isset($sortedResult[$result])){
                        $sortedResult[$result] = 0;
                    }
                    $sortedResult[$result]++;
                }
                asort($sortedResult);//sort the result based on value

                //implode array key
                $wallResult = array();
                foreach($sortedResult as $key => $value) {
                    $wallResult[] = $key;
                }

                //sort by specific id using FIELD
                $order .=!empty($wallResult) ? ' ORDER BY FIELD(  v.' . $db->quoteName('id') . ' , ' . implode(',', $wallResult) . ') DESC' : ' ORDER BY v.' . $db->quoteName('created') . ' DESC';
                break;
            case 'mostviews':
                $order = ' ORDER BY v.' . $db->quoteName('hits') . ' DESC';
                break;
            case 'title':
                $order = ' ORDER BY v.' . $db->quoteName('title') . ' ASC';
                break;
            case 'featured':
                $join .=  ' LEFT JOIN `#__community_featured` f ON f.cid = v.id ';
                $order = ' ORDER BY f.cid DESc, v.id DESC';

                break;
            case 'tagged':
                //@since 4.1.4 to show only tagged videos of the user

                //creator must exists else we wouldnt know whose video are we gonna show
                if(!isset($filters['creator'])){
                    return;
                }

                $videoTagModel = CFactory::getModel('videotagging');
                $taggedVideos = $videoTagModel->getTaggedVideosByUser($filters['creator']);

                if(count($taggedVideos) > 0){
                    $taggedVideosIds = '0';
                    foreach($taggedVideos as $video){
                        $taggedVideosIds .= ','.$video->id;
                    }

                    $where = " WHERE v.`id` IN (".$taggedVideosIds.")"; //overwrite all the previous where stats.
                }

                break;
            case 'latest':
            default :
                $order = ' ORDER BY v.' . $db->quoteName('created') . ' DESC';
                break;
        }

        $query = ' SELECT v.*, v.' . $db->quoteName('created') . ' AS lastupdated'
                . ' FROM ' . $db->quoteName('#__community_videos') . ' AS v'
                . $join
                . $where
                . ' GROUP BY v.id ' 
                . $order
                . $limiter;
        $db->setQuery($query);

        try {
            $result = $db->loadObjectList();
        } catch (Exception $e) {
            Factory::getApplication()->enqueueMessage($e->getMessage(), 'error');
        }

        // bind to Table
        $data = array();
        foreach ($result AS $row) {
            $video = Table::getInstance('Video', 'CTable');
            $video->bind($row);
            $video->lastupdated = $video->created;
            $data[] = $video;
        }

        // Get total of records to be used in the pagination
        $query = ' SELECT COUNT(DISTINCT(v.id))'
                . ' FROM ' . $db->quoteName('#__community_videos') . ' AS v'
                . $join
                . $where;

        $db->setQuery($query);
        
        try {
            $total = $db->loadResult();
        } catch (Exception $e) {
            Factory::getApplication()->enqueueMessage($e->getMessage(), 'error');
        }
        
        $this->total = $total;

        // Apply pagination
        if (empty($this->_pagination)) {
            jimport('joomla.html.pagination');
            $this->_pagination = new Pagination($total, $limitstart, $limit);
        }


        // Add the wallcount property for sorting purpose
        // foreach ($data as $video) {
        // 	// Wall post count
        // 	$query	= ' SELECT COUNT(*)'
        // 			. ' FROM ' . $db->quoteName('#__community_wall')
        // 			. ' WHERE ' . $db->quoteName('type') . ' = ' . $db->quote('videos')
        // 			. ' AND ' . $db->quoteName('published') . ' = ' . $db->quote(1)
        // 			. ' AND ' . $db->quoteName('contentid') . ' = ' . $db->quote($video->id)
        // 			;
        // 	$db->setQuery($query);
        // 	$video->wallcount	= $db->loadResult();
        // }
        // // Sort videos according to wall post count
        // if ($sorting == 'mostwalls')
        // 	JArrayHelper::Joomla\Utilities\ArrayHelper( $data, 'wallcount', -1);

        $resultentriesdata = array('entries' => $data, 'total' => $total, 'limitstart' => $limitstart, 'limit' => $limit);
        if ($useCache) {
            $cache->store($resultentriesdata, $cacheid, array(COMMUNITY_CACHE_TAG_VIDEOS));
        }

        return $data;
    }

    /**
     * Loads the categories
     *
     * @access	public
     * @return	array	An array of categories object
     * @since	1.2
     */
    public function getCategories($categoryId = null) {
        $mainframe = Factory::getApplication();
        $jinput = $mainframe->input;
        $cache = CFactory::getFastCache();
        $cacheid = serialize(func_get_args()) . serialize($jinput->getArray());
        if ($data = $cache->get($cacheid)) {
            return $data;
        }

        $my = CFactory::getUser();
        $permissions = ($my->id == 0) ? 0 : 20;
        $groupId = $jinput->get->get('groupid', '', 'INT');
        $conditions = '';
        $db = $this->getDBO();

        if (!empty($groupId)) {
            $conditions = ' AND v.' . $db->quoteName('creator_type') . ' = ' . $db->quote(VIDEO_GROUP_TYPE);
            //$conditions	.= ' AND b.groupid = ' . $groupId;
            $conditions .= ' AND g.' . $db->quoteName('id') . ' = ' . $db->Quote($groupId);
        } else {
            $conditions .= ' AND (g.' . $db->quoteName('approvals') . ' = ' . $db->Quote('0') . ' OR g.' . $db->quoteName('approvals') . ' IS NULL)';
        }

        $allcats = $this->getAllCategories($categoryId);
        $allCatsNoFilter = $this->getAllCategories();

        $result = array();
        foreach ($allcats as $cat) {
            $categoryIds = CCategoryHelper::getCategoryChilds($allCatsNoFilter, $cat->id);
            if ((int) $cat->id > 0) {
                $categoryIds[] = (int) $cat->id;
            }

            if (is_array($categoryIds)) {
                $categoryIds = implode(',', $categoryIds);
                $categoryCondition = $db->quoteName('category_id') . ' IN (' . $categoryIds . ') ';
            } else {
                $categoryCondition = $db->quoteName('category_id') . ' = ' . $db->Quote($cat->id);
            }
            $query = ' SELECT COUNT(v.' . $db->quoteName('id') . ') AS count'
                    . ' FROM ' . $db->quoteName('#__community_videos') . ' AS v'
                    . ' LEFT JOIN ' . $db->quoteName('#__community_groups') . ' AS g ON g.' . $db->quoteName('id') . ' = v.' . $db->quoteName('groupid')
                    . ' WHERE v.' . $categoryCondition
                    . ' AND v.' . $db->quoteName('status') . ' = ' . $db->Quote('ready')
                    . ' AND v.' . $db->quoteName('published') . ' = ' . $db->Quote(1)
                    . ' AND v.' . $db->quoteName('permissions') . ' <= ' . $db->Quote($permissions)
                    . $conditions;
            $db->setQuery($query);

            try {
                $cat->count = $db->loadResult();
            } catch (Exception $e) {
                Factory::getApplication()->enqueueMessage($e->getMessage(), 'error');
            }
            $result[] = $cat;
        }

        $cache->store($result, $cacheid, array(COMMUNITY_CACHE_TAG_VIDEOS_CAT));
        return $result;
    }

    public function getAllCategories($catId = COMMUNITY_ALL_CATEGORIES) {
        $db = $this->getDBO();

        $where = '';
        if ($catId !== COMMUNITY_ALL_CATEGORIES) {
            if ($catId === COMMUNITY_NO_PARENT) {
                $where = 'WHERE ' . $db->quoteName('parent') . '=' . $db->Quote(COMMUNITY_NO_PARENT) . ' ';
            } else {
                $where = 'WHERE ' . $db->quoteName('parent') . '=' . $db->Quote($catId) . ' ';
            }
        }

        $query = ' SELECT * '
                . ' FROM ' . $db->quoteName('#__community_videos_category')
                . ' ' . $where . ' ORDER BY ' . $db->quoteName('name') . ' ASC';
        $db->setQuery($query);
        $result = $db->loadObjectList();

        // bind to table
        $data = array();
        foreach ($result as $row) {
            $video = Table::getInstance('VideosCategory', 'CTable');
            $video->bind($row);
            $data[] = $video;
        }

        return $data;
    }

    public function getPagination() {
        return $this->_pagination;
    }

    public function getTotal() {
        return $this->total;
    }

    public function getUserTotalVideos($userId, $permission = 10) {
        $mainframe = Factory::getApplication();
        $jinput = $mainframe->input;

        $filters = array
            (
            'creator' => $userId,
            'creator_type' => 'user',
            'status' => 'ready',
            'sorting' => $jinput->get('sort', 'latest', 'STRING'),
            'permissions' => $permission
        );
        $videos = $this->getVideos($filters, false, false);
        return $videos;
    }

    public function deleteVideoWalls($id) {
        if (!$id)
            return;
        $db = $this->getDBO();
        $query = 'DELETE FROM ' . $db->quoteName('#__community_wall')
                . ' WHERE ' . $db->quoteName('contentid') . ' = ' . $db->quote($id)
                . ' AND ' . $db->quoteName('type') . ' = ' . $db->quote('videos');
        $db->setQuery($query);
        try {
            $db->execute();
        } catch (Exception $e) {
            Factory::getApplication()->enqueueMessage($e->getMessage(), 'error');
        }
        return true;
    }

    public function deleteVideoActivities($id = 0) {
        if (!$id)
            return;

        $db = $this->getDBO();
        $query = 'DELETE FROM ' . $db->quoteName('#__community_activities')
                . ' WHERE ('
                        . $db->quoteName('app') . ' = ' . $db->quote('videos')
                        . ' AND ' . $db->quoteName('cid') . ' = ' . $db->quote($id) .')
                    OR (' . $db->quoteName('app') . ' LIKE '.$db->quote('videos.comment')
                         . ' AND '. $db->quoteName('cid'). '= '. $db->quote($id).' )
                    OR (' . $db->quoteName('app') . ' LIKE '.$db->quote('videos.linking')
                        . ' AND '. $db->quoteName('cid'). '= '. $db->quote($id).' )';

        $db->setQuery($query);
        try {
            $db->execute();
        } catch (Exception $e) {
            Factory::getApplication()->enqueueMessage($e->getMessage(), 'error');
        }
        return true;
    }
    
    public function getPageVideos($pageid, $categoryid = "", $limit = "", $sorting = "") {
        $mainframe = Factory::getApplication();
        $jinput = $mainframe->input;
        $filter = array(
            'pageid' => $pageid,
            'published' => 1,
            'status' => 'ready',
            'category_id' => $categoryid,
            'creator_type' => VIDEO_PAGE_TYPE,
            'sorting' => $jinput->get('sort', 'latest', 'STRING'),
            'limit' => $limit
        );

        $videos = $this->getVideos($filter);

        return $videos;
    }
    
    /**
     * Returns Group's videos
     *
     * @access public
     * @param integer the id of the group
     */
    public function getGroupVideos($groupid, $categoryid = "", $limit = "") {
        $mainframe = Factory::getApplication();
        $jinput = $mainframe->input;
        $filter = array(
            'groupid' => $groupid,
            'published' => 1,
            'status' => 'ready',
            'category_id' => $categoryid,
            'creator_type' => VIDEO_GROUP_TYPE,
            'sorting' => $jinput->get('sort', 'latest', 'STRING'),
            'limit' => $limit
        );

        $videos = $this->getVideos($filter);

        return $videos;
    }

    public function getEventVideos($eventid, $categoryid = "", $limit = "") {
        $mainframe = Factory::getApplication();
        $jinput = $mainframe->input;
        $filter = array(
            'eventid' => $eventid,
            'published' => 1,
            'status' => 'ready',
            'category_id' => $categoryid,
            'creator_type' => VIDEOS_EVENT_TYPE,
            'sorting' => $jinput->get('sort', 'latest', 'STRING'),
            'limit' => $limit
        );

        $videos = $this->getVideos($filter);

        return $videos;
    }

    /**
     *
     * @return type
     */
    public function getPendingVideos() {
        $filter = array('status' => 'pending');
        return $this->getVideos($filter, false, true, false);
    }

    /**
     * Get the count of the videos from specific user
     * */
    public function getVideosCount($userId = 0, $videoType = VIDEO_USER_TYPE) {
        if ($userId == 0)
            return 0;

        $db = $this->getDBO();

        $query = 'SELECT COUNT(1) FROM '
                . $db->quoteName('#__community_videos') . ' AS a '
                . 'WHERE ' . $db->quoteName('creator') . '=' . $db->Quote($userId) . ' '
                . 'AND ' . $db->quoteName('creator_type') . '=' . $db->Quote($videoType)
                . ' AND (' . $db->quoteName('status') . ' = ' . $db->quote('ready') . ' OR ' . $db->quoteName('type') . ' = ' . $db->quote('file') . ')';

        $db->setQuery($query);
        $count = $db->loadResult();

        return $count;
    }

    /**
     * Retrieve a list of popular videos from the site.
     *
     * @param   int $limit  The total number of records to return.
     * */
    public function getPopularVideos($limit = 0) {
        $filter = array(
            'published' => 1,
            'status' => 'ready',
            'sorting' => 'mostviews',
            'limit' => $limit
        );

        $result = $this->getVideos($filter);
        $videos = array();
        foreach ($result as $row) {
            $video = Table::getInstance('Video', 'CTable');
            $video->load($row->id);
            $videos[] = $video;
        }
        return $videos;
    }

    // A user updated his view permission, change the permission level for
    // all videos
    public function updatePermission($userid, $permission) {
        $db = $this->getDBO();
        $query = 'UPDATE ' . $db->quoteName('#__community_videos')
                . ' SET ' . $db->quoteName('permissions') . ' = ' . $db->Quote($permission)
                . ' WHERE ' . $db->quoteName('creator') . ' = ' . $db->Quote($userid)
                . ' AND ' . $db->quoteName('groupid') . ' = ' . $db->quote(0);

        $db->setQuery($query);
        try {
            $db->execute();
        } catch (Exception $e) {
            Factory::getApplication()->enqueueMessage($e->getMessage(), 'error');
        }

        return $this;
    }

    /**
     * Return total videos for the day for the specific user.
     *
     * @param	string	$userId	The specific userid.
     * */
    public function getTotalToday($userId) {
        $db = Factory::getDBO();
        $date = JDate::getInstance();

        $query = 'SELECT COUNT(*) FROM ' . $db->quoteName('#__community_videos') . ' AS a WHERE '
                . $db->quoteName('creator') . '=' . $db->Quote($userId) . ' '
                . 'AND TO_DAYS(' . $db->Quote($date->toSql(true)) . ') - TO_DAYS( DATE_ADD( a.' . $db->quoteName('created') . ' , INTERVAL ' . $date->getOffset() . ' HOUR ) ) = 0 ';

        $db->setQuery($query);
        return $db->loadResult();
    }

    /*
      since 2.6
     */

    public function getInviteListByName($namePrefix, $userid, $cid, $limitstart = 0, $limit = 8) {
        $db = $this->getDBO();
        $my = CFactory::getUser();

        $andName = '';
        $config = CFactory::getConfig();
        $nameField = $config->getString('displayname');
        if (!empty($namePrefix)) {
            $andName = ' AND b.' . $db->quoteName($nameField) . ' LIKE ' . $db->Quote('%' . $namePrefix . '%');
        }

        //we will treat differently for member's video and group's video
        $video = Table::getInstance('Video', 'CTable');
        $video->load($cid);
        if ($video->groupid) {
            $countQuery = 'SELECT COUNT(DISTINCT(a.' . $db->quoteName('memberid') . '))  FROM ' . $db->quoteName('#__community_groups_members') . ' AS a ';
            $listQuery = 'SELECT DISTINCT(a.' . $db->quoteName('memberid') . ') AS id  FROM ' . $db->quoteName('#__community_groups_members') . ' AS a ';
            $joinQuery = ' INNER JOIN ' . $db->quoteName('#__users') . ' AS b '
                    . ' ON a.' . $db->quoteName('memberid') . '=b.' . $db->quoteName('id')
                    . ' AND a.' . $db->quoteName('approved') . '=' . $db->Quote(1)
                    . ' AND a.' . $db->quoteName('memberid') . '!=' . $db->Quote($my->id)
                    . ' AND a.' . $db->quoteName('groupid') . '=' . $db->Quote($video->groupid)
                    . ' WHERE NOT EXISTS (SELECT e.' . $db->quoteName('userid') . ' as id'
                    . ' FROM ' . $db->quoteName('#__community_videos_tag') . ' AS e  '
                    . ' WHERE e.' . $db->quoteName('videoid') . ' = ' . $db->Quote($cid)
                    . ' AND e.' . $db->quoteName('userid') . ' = a.' . $db->quoteName('memberid')
                    . ')';
        } else {
            $countQuery = 'SELECT COUNT(DISTINCT(a.' . $db->quoteName('connect_to') . ')) FROM ' . $db->quoteName('#__community_connection') . ' AS a ';
            $listQuery = 'SELECT DISTINCT(a.' . $db->quoteName('connect_to') . ') AS id  FROM ' . $db->quoteName('#__community_connection') . ' AS a ';
            $joinQuery = ' INNER JOIN ' . $db->quoteName('#__users') . ' AS b '
                    . ' ON a.' . $db->quoteName('connect_from') . '=' . $db->Quote($userid)
                    . ' AND a.' . $db->quoteName('connect_to') . '=b.' . $db->quoteName('id')
                    . ' AND a.' . $db->quoteName('status') . '=' . $db->Quote('1')
                    . ' AND b.' . $db->quoteName('block') . '=' . $db->Quote('0')
                    . ' WHERE NOT EXISTS ( SELECT d.' . $db->quoteName('blocked_userid') . ' as id'
                    . ' FROM ' . $db->quoteName('#__community_blocklist') . ' AS d  '
                    . ' WHERE d.' . $db->quoteName('userid') . ' = ' . $db->Quote($userid)
                    . ' AND d.' . $db->quoteName('blocked_userid') . ' = a.' . $db->quoteName('connect_to') . ')'
                    . ' AND NOT EXISTS (SELECT e.' . $db->quoteName('userid') . ' as id'
                    . ' FROM ' . $db->quoteName('#__community_videos_tag') . ' AS e  '
                    . ' WHERE e.' . $db->quoteName('videoid') . ' = ' . $db->Quote($cid)
                    . ' AND e.' . $db->quoteName('userid') . ' = a.' . $db->quoteName('connect_to')
                    . ')';
        }
        $query = $listQuery . $joinQuery . $andName
                . ' ORDER BY b.' . $db->quoteName($nameField)
                . ' LIMIT ' . $limitstart . ',' . $limit;
        $db->setQuery($query);
        $friends = $db->loadColumn();

        //calculate total
        $query = $countQuery . $joinQuery . $andName;
        $db->setQuery($query);
        $this->total = $db->loadResult();
        //friend yourself
        if ($my->id) {
            if ($namePrefix === '') {
                $found = false;
            } else {
                $found = CStringHelper::strpos($my->getDisplayName(), $namePrefix);
            }
            if ($namePrefix == '' || $found || $found === 0) {
                array_unshift($friends, $my->id);
                $this->total = $this->total + 1;
            }
        }
        return $friends;
    }

    public function getTotalSiteVideos() {
        $db = $this->getDBO();

        $query = 'SELECT COUNT(1) FROM ' . $db->quoteName('#__community_videos') . ' '
                . 'WHERE ' . $db->quoteName('published') . '=' . $db->Quote(1);

        $db->setQuery($query);
        try {
            $total = $db->loadResult();
        } catch (Exception $e) {
            Factory::getApplication()->enqueueMessage($e->getMessage(), 'error');
        }

        return $total;
    }

    /**
     * @param $id video id
     * @param $videoName videoname
     * Delete the original video if there is a callback from zencoder notification
     * @return bool
     */
    public function zencoderCallback($id, $videoName)
    {
        $video = Table::getInstance('Video', 'CTable');
        $video->load($id);

        $videoNameChunk = explode('.', $videoName); // little security to prevent ".."
        //to make sure the video is in s3
        if ($video->storage == 's3' && $video->status == 'ready' && count($videoNameChunk) == 2) {
            $videoIn = Path::clean(JPATH_ROOT . '/' . CFactory::getConfig()->get('videofolder') . '/' . ORIGINAL_VIDEO_FOLDER_NAME . '/' . $video->creator . '/' . $videoName);
            $deleteOriginal = CFactory::getConfig()->get('deleteoriginalvideos');

            if ($deleteOriginal) {
                File::delete($videoIn);
                return true;
            }
        }
        return false;
    }

}

abstract class CVideoProvider extends cobject {

    abstract function getThumbnail();

    abstract function getTitle();

    abstract function getDuration();

    abstract function getType();

    abstract function getId();

    abstract function getViewHTML($videoId, $videoWidth, $videoHeight);

    public function __construct($db = null) {
        parent::__construct();
    }

    /**
     * Initialize the provider with video url resource
     */
    public function init($url) {
        $this->url = $url;
        $this->videoId = $this->getId();
    }

    /**
     * Return embedded code
     *
     * @param type $videoId
     * @param type $videoWidth
     * @param type $videoHeight
     * @return type
     *
     */
    public function getEmbedCode($videoId, $videoWidth, $videoHeight) {
        return $this->getViewHTML($videoId, $videoWidth, $videoHeight);
    }

    /**
     * Return true if the video is valid.
     * This function uses a typical video privider method where they normally provide
     * a XML feed file to extract all the video info
     * @return type Boolean
     */
    public function isValid() {
        // Connect and get the remote video
        // Simple check, make sure video id exist
        if (empty($this->videoId)) {
            throw new Exception(Text::_('COM_COMMUNITY_VIDEOS_INVALID_VIDEO_ID_ERROR'));
            return false;
        }
        // Youtube might return 'Video not found' in the content file
        $this->xmlContent = CRemoteHelper::getContent($this->getFeedUrl());
        if ($this->xmlContent == false) {
            throw new Exception(Text::_('COM_COMMUNITY_VIDEOS_FETCHING_VIDEO_ERROR'));
            return false;
        }


        return true;
    }
}
