<commit_before><?php
/**
 * DoubleClick Service
 *
 * @service doubleClick
 * @package plugins.doubleClickDistribution
 * @subpackage api.services
 */
class DoubleClickService extends KalturaBaseService
{
	public function initService($serviceId, $serviceName, $actionName)
	{
		parent::initService($serviceId, $serviceName, $actionName);
	}
	
	/**
	 * @action getFeed
	 * @param int $distributionProfileId
	 * @param string $hash
	 * @param int $page
	 * @param int $period
	 * @param string $state
	 * @return file
	 */
	public function getFeedAction($distributionProfileId, $hash, $page = 1, $period = -1, $state = '')
	{
		if (!$this->getPartnerId() || !$this->getPartner())
			throw new KalturaAPIException(KalturaErrors::INVALID_PARTNER_ID, $this->getPartnerId());
			
		$profile = DistributionProfilePeer::retrieveByPK($distributionProfileId);
		if (!$profile || !$profile instanceof DoubleClickDistributionProfile)
			throw new KalturaAPIException(ContentDistributionErrors::DISTRIBUTION_PROFILE_NOT_FOUND, $distributionProfileId);

		if ($profile->getStatus() != KalturaDistributionProfileStatus::ENABLED)
			throw new KalturaAPIException(ContentDistributionErrors::DISTRIBUTION_PROFILE_DISABLED, $distributionProfileId);

		if ($profile->getUniqueHashForFeedUrl() != $hash)
			throw new KalturaAPIException(DoubleClickDistributionErrors::INVALID_FEED_URL);

		if (!$page || $page < 1)
			$page = 1;

		$stateLastEntryCreatedAt = null;
		$stateLastEntryIds = array();
		if ($state) 
		{
			$stateDecoded = base64_decode($state);
			if (strpos($stateDecoded, '|') !== false) 
			{
				$stateExploded = explode('|', $stateDecoded);
				$stateLastEntryCreatedAt = $stateExploded[0];
				$stateLastEntryIdsStr =  $stateExploded[1];
				$stateLastEntryIds = explode(',', $stateLastEntryIdsStr);
			}
		}

		// "Creates advanced filter on distribution profile
		$distributionAdvancedSearch = new ContentDistributionSearchFilter();
		$distributionAdvancedSearch->setDistributionProfileId($profile->getId());
		$distributionAdvancedSearch->setDistributionSunStatus(EntryDistributionSunStatus::AFTER_SUNRISE);
		$distributionAdvancedSearch->setEntryDistributionStatus(EntryDistributionStatus::READY);
		$distributionAdvancedSearch->setEntryDistributionFlag(EntryDistributionDirtyStatus::NONE);
		$distributionAdvancedSearch->setHasEntryDistributionValidationErrors(false);
			
		// Creates entry filter with advanced filter
		$entryFilter = new entryFilter();
		$entryFilter->setStatusEquel(entryStatus::READY);
		$entryFilter->setModerationStatusNot(entry::ENTRY_MODERATION_STATUS_REJECTED);
		$entryFilter->setPartnerIdEquel($this->getPartnerId());
		$entryFilter->setAdvancedSearch($distributionAdvancedSearch);
		$entryFilter->set('_order_by', '-created_at');
		if ($period && $period > 0)
			$entryFilter->set('_gte_updated_at', time() - 24*60*60); // last 24 hours
			
		// Dummy query to get the total count
		$baseCriteria = KalturaCriteria::create(entryPeer::OM_CLASS);
		$baseCriteria->setLimit(1);
		$entryFilter->attachToCriteria($baseCriteria);
		$entries = entryPeer::doSelect($baseCriteria);
		$totalCount = $baseCriteria->getRecordsCount();
		
		// Add the state data to proceed to next page
		if ($stateLastEntryCreatedAt)
			$entryFilter->set('_lte_created_at', $stateLastEntryCreatedAt);
		if ($stateLastEntryIds)
			$entryFilter->set('_notin_id', $stateLastEntryIds);

		$baseCriteria = KalturaCriteria::create(entryPeer::OM_CLASS);
		$baseCriteria->setLimit($profile->getItemsPerPage() + 1); // get +1 to check if we have next page
		$entryFilter->attachToCriteria($baseCriteria);
		$entries = entryPeer::doSelect($baseCriteria);

		$hasNextPage = false;
		if (count($entries) === ($profile->getItemsPerPage() + 1)) { // we tried to get (itemsPerPage + 1) entries, meaning we have another page
			$hasNextPage = true;
			unset($entries[$profile->getItemsPerPage()]);
		}

		// Find the state
		$entryIds = array();
		$nextPageStateLastEntryCreatedAt = $stateLastEntryCreatedAt;
		$nextPageStateLastEntryIds = $stateLastEntryIds;
		foreach($entries as $entry)
		{
			$entryIds[] = $entry->getId();
			
			if ($nextPageStateLastEntryCreatedAt > $entry->getCreatedAt(null))
				$nextPageStateLastEntryIds = array();
			
			$nextPageStateLastEntryIds[] = $entry->getId();
			$nextPageStateLastEntryCreatedAt = $entry->getCreatedAt(null);
		}
		
		// Construct the feed
		$feed = new DoubleClickFeed('doubleclick_template.xml', $profile);
		$feed->setTotalResult($totalCount);
		$feed->setStartIndex(($page - 1) * $profile->getItemsPerPage() + 1);
		$feed->setSelfLink($this->getUrl($distributionProfileId, $hash, $page, $period, $stateLastEntryCreatedAt, $stateLastEntryIds));
		if ($hasNextPage)
			$feed->setNextLink($this->getUrl($distributionProfileId, $hash, $page + 1, $period, $nextPageStateLastEntryCreatedAt, $nextPageStateLastEntryIds));
	
		$cacheDir = kConf::get("global_cache_dir")."double_click/";	
		foreach($entries as $entry)
		{
			// check cache
			$cacheFileName = $cacheDir.myContentStorage::dirForId($entry->getIntId(), $entry->getId().".xml");
			if (file_exists($cacheFileName) && $entry->getUpdatedAt() < filemtime($cacheFileName))
			{
				$xml = file_get_contents($cacheFileName);
			}
			else
			{
			/* @var $entry entry */
			$entryDistribution = EntryDistributionPeer::retrieveByEntryAndProfileId($entry->getId(), $profile->getId());
			if (!$entryDistribution)
			{
				KalturaLog::err('Entry distribution was not found for entry ['.$entry->getId().'] and profile [' . $profile->getId() . ']');
				continue;
			}
			$fields = $profile->getAllFieldValues($entryDistribution);
			$flavorAssets = assetPeer::retrieveByIds(explode(',', $entryDistribution->getFlavorAssetIds()));
			$thumbAssets = assetPeer::retrieveByIds(explode(',', $entryDistribution->getThumbAssetIds()));
			
			$cuePoints = $this->getCuePoints($entry->getPartnerId(), $entry->getId());
			$xml = $feed->getItemXml($fields, $flavorAssets, $thumbAssets, $cuePoints);
			mkdir(dirname($cacheFileName), 0777, true);<commit_msg>qnd: changed getUpdatedAt() to getUpdatedAt(null) for numeric comparison<commit_after><?php
/**
 * DoubleClick Service
 *
 * @service doubleClick
 * @package plugins.doubleClickDistribution
 * @subpackage api.services
 */
class DoubleClickService extends KalturaBaseService
{
	public function initService($serviceId, $serviceName, $actionName)
	{
		parent::initService($serviceId, $serviceName, $actionName);
	}
	
	/**
	 * @action getFeed
	 * @param int $distributionProfileId
	 * @param string $hash
	 * @param int $page
	 * @param int $period
	 * @param string $state
	 * @return file
	 */
	public function getFeedAction($distributionProfileId, $hash, $page = 1, $period = -1, $state = '')
	{
		if (!$this->getPartnerId() || !$this->getPartner())
			throw new KalturaAPIException(KalturaErrors::INVALID_PARTNER_ID, $this->getPartnerId());
			
		$profile = DistributionProfilePeer::retrieveByPK($distributionProfileId);
		if (!$profile || !$profile instanceof DoubleClickDistributionProfile)
			throw new KalturaAPIException(ContentDistributionErrors::DISTRIBUTION_PROFILE_NOT_FOUND, $distributionProfileId);

		if ($profile->getStatus() != KalturaDistributionProfileStatus::ENABLED)
			throw new KalturaAPIException(ContentDistributionErrors::DISTRIBUTION_PROFILE_DISABLED, $distributionProfileId);

		if ($profile->getUniqueHashForFeedUrl() != $hash)
			throw new KalturaAPIException(DoubleClickDistributionErrors::INVALID_FEED_URL);

		if (!$page || $page < 1)
			$page = 1;

		$stateLastEntryCreatedAt = null;
		$stateLastEntryIds = array();
		if ($state) 
		{
			$stateDecoded = base64_decode($state);
			if (strpos($stateDecoded, '|') !== false) 
			{
				$stateExploded = explode('|', $stateDecoded);
				$stateLastEntryCreatedAt = $stateExploded[0];
				$stateLastEntryIdsStr =  $stateExploded[1];
				$stateLastEntryIds = explode(',', $stateLastEntryIdsStr);
			}
		}

		// "Creates advanced filter on distribution profile
		$distributionAdvancedSearch = new ContentDistributionSearchFilter();
		$distributionAdvancedSearch->setDistributionProfileId($profile->getId());
		$distributionAdvancedSearch->setDistributionSunStatus(EntryDistributionSunStatus::AFTER_SUNRISE);
		$distributionAdvancedSearch->setEntryDistributionStatus(EntryDistributionStatus::READY);
		$distributionAdvancedSearch->setEntryDistributionFlag(EntryDistributionDirtyStatus::NONE);
		$distributionAdvancedSearch->setHasEntryDistributionValidationErrors(false);
			
		// Creates entry filter with advanced filter
		$entryFilter = new entryFilter();
		$entryFilter->setStatusEquel(entryStatus::READY);
		$entryFilter->setModerationStatusNot(entry::ENTRY_MODERATION_STATUS_REJECTED);
		$entryFilter->setPartnerIdEquel($this->getPartnerId());
		$entryFilter->setAdvancedSearch($distributionAdvancedSearch);
		$entryFilter->set('_order_by', '-created_at');
		if ($period && $period > 0)
			$entryFilter->set('_gte_updated_at', time() - 24*60*60); // last 24 hours
			
		// Dummy query to get the total count
		$baseCriteria = KalturaCriteria::create(entryPeer::OM_CLASS);
		$baseCriteria->setLimit(1);
		$entryFilter->attachToCriteria($baseCriteria);
		$entries = entryPeer::doSelect($baseCriteria);
		$totalCount = $baseCriteria->getRecordsCount();
		
		// Add the state data to proceed to next page
		if ($stateLastEntryCreatedAt)
			$entryFilter->set('_lte_created_at', $stateLastEntryCreatedAt);
		if ($stateLastEntryIds)
			$entryFilter->set('_notin_id', $stateLastEntryIds);

		$baseCriteria = KalturaCriteria::create(entryPeer::OM_CLASS);
		$baseCriteria->setLimit($profile->getItemsPerPage() + 1); // get +1 to check if we have next page
		$entryFilter->attachToCriteria($baseCriteria);
		$entries = entryPeer::doSelect($baseCriteria);

		$hasNextPage = false;
		if (count($entries) === ($profile->getItemsPerPage() + 1)) { // we tried to get (itemsPerPage + 1) entries, meaning we have another page
			$hasNextPage = true;
			unset($entries[$profile->getItemsPerPage()]);
		}

		// Find the state
		$entryIds = array();
		$nextPageStateLastEntryCreatedAt = $stateLastEntryCreatedAt;
		$nextPageStateLastEntryIds = $stateLastEntryIds;
		foreach($entries as $entry)
		{
			$entryIds[] = $entry->getId();
			
			if ($nextPageStateLastEntryCreatedAt > $entry->getCreatedAt(null))
				$nextPageStateLastEntryIds = array();
			
			$nextPageStateLastEntryIds[] = $entry->getId();
			$nextPageStateLastEntryCreatedAt = $entry->getCreatedAt(null);
		}
		
		// Construct the feed
		$feed = new DoubleClickFeed('doubleclick_template.xml', $profile);
		$feed->setTotalResult($totalCount);
		$feed->setStartIndex(($page - 1) * $profile->getItemsPerPage() + 1);
		$feed->setSelfLink($this->getUrl($distributionProfileId, $hash, $page, $period, $stateLastEntryCreatedAt, $stateLastEntryIds));
		if ($hasNextPage)
			$feed->setNextLink($this->getUrl($distributionProfileId, $hash, $page + 1, $period, $nextPageStateLastEntryCreatedAt, $nextPageStateLastEntryIds));
	
		$cacheDir = kConf::get("global_cache_dir")."double_click/";	
		foreach($entries as $entry)
		{
			// check cache
			$cacheFileName = $cacheDir.myContentStorage::dirForId($entry->getIntId(), $entry->getId().".xml");
			if (file_exists($cacheFileName) && $entry->getUpdatedAt(null) < filemtime($cacheFileName))
			{
				$xml = file_get_contents($cacheFileName);
			}
			else
			{
			/* @var $entry entry */
			$entryDistribution = EntryDistributionPeer::retrieveByEntryAndProfileId($entry->getId(), $profile->getId());
			if (!$entryDistribution)
			{
				KalturaLog::err('Entry distribution was not found for entry ['.$entry->getId().'] and profile [' . $profile->getId() . ']');
				continue;
			}
			$fields = $profile->getAllFieldValues($entryDistribution);
			$flavorAssets = assetPeer::retrieveByIds(explode(',', $entryDistribution->getFlavorAssetIds()));
			$thumbAssets = assetPeer::retrieveByIds(explode(',', $entryDistribution->getThumbAssetIds()));
			
			$cuePoints = $this->getCuePoints($entry->getPartnerId(), $entry->getId());
			$xml = $feed->getItemXml($fields, $flavorAssets, $thumbAssets, $cuePoints);
			mkdir(dirname($cacheFileName), 0777, true);
{'fraction_non_alphanumeric': 0.14483326471799093, 'fraction_numerical': 0.004775627830382874, 'mean_word_length': 6.020809248554913, 'pattern_counts': {'":': 0, '<': 9, '<?xml version=': 0, '>': 113, 'https://': 0, 'lorem ipsum': 0, 'www.': 0, 'xml': 8}, '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': '2565354', 'n_tokens_mistral': 4153, 'n_tokens_neox': 3651, 'n_words': 648}