Your IP : 18.116.88.16


Current Path : /home/bitrix/ext_www/crm.klimatlend.ua/bitrix/modules/crm/lib/volume/
Upload File :
Current File : /home/bitrix/ext_www/crm.klimatlend.ua/bitrix/modules/crm/lib/volume/emailattachment.php

<?php

namespace Bitrix\Crm\Volume;

use Bitrix\Crm;
use Bitrix\Crm\Volume;
use Bitrix\Disk;
use Bitrix\Main;
use Bitrix\Main\ORM;
use Bitrix\Main\Entity;
use Bitrix\Main\Localization\Loc;


class EmailAttachment
	extends Volume\Base
	implements Volume\IVolumeClear, Volume\IVolumeClearFile, Volume\IVolumeUrl
{
	/** @var Volume\Activity */
	private $activityFiles;

	/**
	 * Returns title of the indicator.
	 * @return string
	 */
	public function getTitle()
	{
		return Loc::getMessage('CRM_VOLUME_EMAIL_TITLE');
	}

	/**
	 * Returns availability to drop entity.
	 *
	 * @return boolean
	 */
	public function canClearEntity()
	{
		return true;
	}

	/**
	 * Returns availability to drop entity attachments.
	 *
	 * @return boolean
	 */
	public function canClearFile()
	{
		return $this->canClearEntity();
	}

	/**
	 * Can filter applied to the indicator.
	 * @return boolean
	 */
	public function canBeFiltered()
	{
		return true;
	}

	/**
	 * Tells that is is participated in the total volume.
	 * @return boolean
	 */
	public function isParticipatedTotal()
	{
		return false;
	}

	/**
	 * Get entity list path.
	 * @return string
	 */
	public function getUrl()
	{
		static $entityListPath;
		if($entityListPath === null)
		{
			$entityListPath = \CComponentEngine::MakePathFromTemplate(
				\Bitrix\Main\Config\Option::get('crm', 'path_to_activity_list', '/crm/activity/')
			);
		}

		return $entityListPath;
	}

	/**
	 * Get filter reset params for entity grid.
	 * @return array
	 */
	public function getGridFilterResetParam()
	{
		$entityListReset = array(
			'FILTER_ID' => 'CRM_ACTIVITY_LIST_MY_ACTIVITIES',
			'GRID_ID' => 'CRM_ACTIVITY_LIST_MY_ACTIVITIES',
			'FILTER_FIELDS' => 'CREATED,TYPE_ID',
		);

		return $entityListReset;
	}

	/**
	 * Get filter alias for url to entity list path.
	 * @return array
	 */
	public function getFilterAlias()
	{
		return array(
			'DATE_CREATE' => 'CREATED',
		);
	}

	/**
	 * Component action list for measure process.
	 * @param array $componentCommandAlias Command alias.
	 * @return array
	 */
	public function getActionList($componentCommandAlias)
	{
		return $this->prepareRangeActionList(
			Crm\ActivityTable::class,
			'CREATED',
			array(
				'MEASURE_ENTITY' => $componentCommandAlias['MEASURE_ENTITY'],
				'MEASURE_FILE' => $componentCommandAlias['MEASURE_FILE'],
			)
		);
	}

	/**
	 * Runs measure test for files.
	 * @return self
	 */
	public function measureEntity()
	{
		self::loadTablesInformation();

		$activity = new Volume\Activity();
		$activity->setFilter($this->getFilter());

		$activityQuery = $activity->prepareQuery();

		$activity->prepareFilter($activityQuery);

		// only email attachments
		$activityQuery->where('TYPE_ID', '=', \CCrmActivityType::Email);

		$activityCount = new ORM\Fields\ExpressionField('ACTIVITY_COUNT', 'COUNT(DISTINCT %s)', 'ID');
		$activityBindingCount = new ORM\Fields\ExpressionField('BINDINGS_COUNT', 'COUNT(%s)', 'BINDINGS.ID');
		$activityQuery
			->registerRuntimeField($activityCount)
			->registerRuntimeField($activityBindingCount)
			->addSelect('ACTIVITY_COUNT')
			->addSelect('BINDINGS_COUNT');

		$entityGroupField = array(
			'DATE_CREATE' => 'DATE_CREATED_SHORT',
			'STAGE_SEMANTIC_ID' => 'STAGE_SEMANTIC_ID',
		);
		foreach ($entityGroupField as $alias => $field)
		{
			$activityQuery->addSelect($field, $alias);
			$activityQuery->addGroup($field);
		}

		$querySql = $activityQuery->getQuery();

		if ($querySql != '')
		{
			$avgActivityTableRowLength = (double)self::$tablesInformation[Crm\ActivityTable::getTableName()]['AVG_SIZE'];
			$avgBindingTableRowLength = (double)self::$tablesInformation[Crm\ActivityBindingTable::getTableName()]['AVG_SIZE'];

			$querySql = "
				SELECT 
					'".static::getIndicatorId()."' as INDICATOR_TYPE,
					'".$this->getOwner()."' as OWNER_ID,
					DATE_CREATE,
					STAGE_SEMANTIC_ID, 
					(
						ACTIVITY_COUNT * {$avgActivityTableRowLength} + 
						BINDINGS_COUNT * {$avgBindingTableRowLength} ) as ACTIVITY_SIZE,
					ACTIVITY_COUNT
				FROM 
				(
					{$querySql}
				) src
			";

			$connection = \Bitrix\Main\Application::getConnection();

			$this->checkTemporally();

			$data = array(
				'INDICATOR_TYPE' => '',
				'OWNER_ID' => '',
				'DATE_CREATE' => new \Bitrix\Main\Type\Date(),
				'STAGE_SEMANTIC_ID' => '',
				'ENTITY_SIZE' => '',
				'ENTITY_COUNT' => '',
			);

			$insert = $connection->getSqlHelper()->prepareInsert(Crm\VolumeTmpTable::getTableName(), $data);

			$sqlIns = 'INSERT INTO '.$connection->getSqlHelper()->quote(Crm\VolumeTmpTable::getTableName()). '('. $insert[0]. ') ';

			$querySql = $sqlIns. $querySql;

			$connection->queryExecute($querySql);

			$this->copyTemporallyData();
		}

		return $this;
	}


	/**
	 * Runs measure test for files.
	 * @return self
	 */
	public function measureFiles()
	{
		$entityGroupField = array(
			'DATE_CREATE' => 'DATE_CREATED_SHORT',
			'STAGE_SEMANTIC' => 'STAGE_SEMANTIC_ID',
		);

		$activityQuery = $this->prepareQuery($entityGroupField);

		// only email attachments
		//$activityQuery->where('TYPE_ID', '=', \CCrmActivityType::Email);

		foreach ($entityGroupField as $alias => $field)
		{
			$activityQuery->addSelect($field, $alias);
			$activityQuery->addGroup($field);
		}

		$activityQuery->addFilter('>FILE_COUNT', 0);

		$querySql = $activityQuery->getQuery();

		if ($querySql != '')
		{
			$querySql = "
				SELECT 
					'".static::getIndicatorId()."' as INDICATOR_TYPE,
					'".$this->getOwner()."' as OWNER_ID,
					DATE_CREATE,
					STAGE_SEMANTIC, 
					SUM(FILE_SIZE) as FILE_SIZE,
					SUM(FILE_COUNT) as FILE_COUNT,
					SUM(DISK_SIZE) as DISK_SIZE,
					SUM(DISK_COUNT) as DISK_COUNT
				FROM 
				(
					{$querySql}
				) src
				GROUP BY
					DATE_CREATE,
					STAGE_SEMANTIC
			";

			Crm\VolumeTable::updateFromSelect(
				$querySql,
				array(
					'FILE_SIZE' => 'destination.FILE_SIZE + source.FILE_SIZE',
					'FILE_COUNT' => 'destination.FILE_COUNT + source.FILE_COUNT',
					'DISK_SIZE' => 'destination.DISK_SIZE + source.DISK_SIZE',
					'DISK_COUNT' => 'destination.DISK_COUNT + source.DISK_COUNT',
				),
				array(
					'INDICATOR_TYPE' => 'INDICATOR_TYPE',
					'OWNER_ID' => 'OWNER_ID',
					'DATE_CREATE' => 'DATE_CREATE',
					'STAGE_SEMANTIC_ID' => 'STAGE_SEMANTIC',
				)
			);
		}

		$connection = \Bitrix\Main\Application::getConnection();
		$sqlDel = "
			DELETE FROM ".$connection->getSqlHelper()->quote(Crm\VolumeTable::getTableName())." 
			WHERE 
				INDICATOR_TYPE = '".static::getIndicatorId()."' AND
				OWNER_ID = '".$this->getOwner()."' AND
				FILE_COUNT = 0
		";
		$connection->queryExecute($sqlDel);

		return $this;
	}

	/**
	 * Performs dropping entity.
	 *
	 * @return boolean
	 */
	public function clearEntity()
	{
		if (!$this->canClearEntity())
		{
			return false;
		}

		$query = $this->prepareQuery();

		$success = true;

		if ($this->prepareFilter($query))
		{
			$userPermissions = \CCrmPerms::GetUserPermissions($this->getOwner());
			$diskAvailable = \Bitrix\Main\Loader::includeModule('disk');
			$exceptMailTemplateAttachment = Volume\MailTemplate::getAttachmentList();

			$query
				//->where('TYPE_ID', '=', \CCrmActivityType::Email)// Email
				->setSelect(array('ID', 'OWNER_TYPE_ID', 'OWNER_ID'))
				->setLimit(self::MAX_ENTITY_PER_INTERACTION)
				->setOrder(array('ID' => 'ASC'));

			if ($this->getProcessOffset() > 0)
			{
				$query->where('ID', '>', $this->getProcessOffset());
			}

			$res = $query->exec();

			while ($activity = $res->fetch())
			{
				$this->setProcessOffset($activity['ID']);

				if (\CCrmActivity::CheckItemDeletePermission($activity, $userPermissions))
				{
					$activityElementList = Crm\ActivityElementTable::getList(array(
						'filter' => array('=ACTIVITY_ID' => $activity['ID']),
						'select' => array('STORAGE_TYPE_ID', 'ELEMENT_ID'),
					));

					// check existence and force removing
					$failOccurred = false;
					while ($row = $activityElementList->fetch())
					{
						// ignoring mail template attachments
						if (in_array((int)$row['ELEMENT_ID'], $exceptMailTemplateAttachment))
						{
							continue;
						}
						$elementIds = array($row['ELEMENT_ID']);
						if (\CCrmActivity::DeleteStorageElements($activity['ID'], array('STORAGE_ELEMENT_IDS' => $elementIds)))
						{
							if ($row['STORAGE_TYPE_ID'] == Crm\Integration\StorageType::File)
							{
								\CFile::Delete($row['ELEMENT_ID']);
							}
							elseif ($row['STORAGE_TYPE_ID'] == Crm\Integration\StorageType::Disk && $diskAvailable)
							{
								$file = \Bitrix\Disk\File::getById($row['ELEMENT_ID']);
								if ($file instanceof \Bitrix\Disk\File)
								{
									if(!$file->delete(\Bitrix\Disk\SystemUser::SYSTEM_USER_ID))
									{
										$this->collectError($file->getErrors());
									}
								}
							}
						}
						else
						{
							$failOccurred = true;
							$error = \CCrmActivity::GetLastErrorMessage();
							if (empty($error))
							{
								$error = 'Deletion failed with activity #'.$activity['ID'];
							}
							$this->collectError(new Main\Error($error,self::ERROR_DELETION_FAILED));
							$this->incrementFailCount();
						}
					}
					if ($failOccurred !== true)
					{
						// drop activity
						if (\CCrmActivity::Delete($activity['ID'], false, false))
						{
							$this->incrementDroppedEntityCount();
						}
						else
						{
							$this->collectError(new Main\Error('Deletion failed with activity #'.$activity['ID'], self::ERROR_DELETION_FAILED));
							$this->incrementFailCount();
						}
					}
				}
				else
				{
					$this->collectError(new Main\Error('Access denied to activity #'.$activity['ID'], self::ERROR_PERMISSION_DENIED));
					$this->incrementFailCount();
				}

				if ($this->hasTimeLimitReached())
				{
					$success = false;
					break;
				}
			}
		}

		return $success;
	}

	/**
	 * Returns count of entities.
	 *
	 * @return int
	 */
	public function countEntity()
	{
		$count = -1;

		$query = $this->prepareQuery();

		if ($this->prepareFilter($query))
		{
			$count = 0;

			$query
				//->where('TYPE_ID', '=', \CCrmActivityType::Email)// Email
				->registerRuntimeField(new ORM\Fields\ExpressionField('CNT', 'COUNT(%s)', 'ID'))
				->addSelect('CNT');

			$res = $query->exec();
			if ($row = $res->fetch())
			{
				$count = $row['CNT'];
			}
		}

		return $count;
	}


	/**
	 * Returns query.
	 * @param  array $entityGroupField Fileds for groupping.
	 * @return ORM\Query\Query
	 */
	public function prepareQuery($entityGroupField = array())
	{
		$this->activityFiles = new Volume\Activity();
		$this->activityFiles->setFilter($this->getFilter());

		$query = $this->activityFiles->getActivityFileMeasureQuery(Volume\Activity::className(), $entityGroupField);

		// only email attachments
		$query->where('TYPE_ID', '=', \CCrmActivityType::Email);

		return $query;
	}

	/**
	 * Setups filter params into query.
	 *
	 * @param ORM\Query\Query $query Query.
	 *
	 * @return boolean
	 */
	public function prepareFilter(ORM\Query\Query $query)
	{
		return $this->activityFiles->prepareFilter($query);
	}

	/**
	 * Performs dropping entity attachments.
	 *
	 * @return boolean
	 */
	public function clearFiles()
	{
		if (!$this->canClearEntity())
		{
			return false;
		}

		$query = $this->prepareQuery();

		$success = true;

		if ($this->prepareFilter($query))
		{
			$userPermissions = \CCrmPerms::GetUserPermissions($this->getOwner());
			$diskAvailable = \Bitrix\Main\Loader::includeModule('disk');
			$exceptMailTemplateAttachment = Volume\MailTemplate::getAttachmentList();

			$query
				//->where('TYPE_ID', '=', \CCrmActivityType::Email)
				->setSelect(array('ID', 'OWNER_TYPE_ID', 'OWNER_ID'))
				->setLimit(self::MAX_ENTITY_PER_INTERACTION)
				->setOrder(array('ID' => 'ASC'));

			if ($this->getProcessOffset() > 0)
			{
				$query->where('ID', '>', $this->getProcessOffset());
			}

			$res = $query->exec();

			while ($activity = $res->fetch())
			{
				$this->setProcessOffset($activity['ID']);

				if (\CCrmActivity::CheckItemDeletePermission($activity, $userPermissions))
				{
					$activityElementList = Crm\ActivityElementTable::getList(array(
						'filter' => array('=ACTIVITY_ID' => $activity['ID']),
						'select' => array('STORAGE_TYPE_ID', 'ELEMENT_ID'),
					));

					// check existence and force removing
					while ($row = $activityElementList->fetch())
					{
						// ignore mail template attachments
						if (in_array((int)$row['ELEMENT_ID'], $exceptMailTemplateAttachment))
						{
							$this->incrementFailCount();
							continue;
						}
						$elementIds = array($row['ELEMENT_ID']);
						if (\CCrmActivity::DeleteStorageElements($activity['ID'], array('STORAGE_ELEMENT_IDS' => $elementIds)))
						{
							if ($row['STORAGE_TYPE_ID'] == Crm\Integration\StorageType::File)
							{
								\CFile::Delete($row['ELEMENT_ID']);
							}
							elseif ($row['STORAGE_TYPE_ID'] == Crm\Integration\StorageType::Disk && $diskAvailable)
							{
								$file = \Bitrix\Disk\File::getById($row['ELEMENT_ID']);
								if ($file instanceof \Bitrix\Disk\File)
								{
									if(!$file->delete(\Bitrix\Disk\SystemUser::SYSTEM_USER_ID))
									{
										$this->collectError($file->getErrors());
									}
								}
							}
							$this->incrementDroppedFileCount();
						}
						else
						{
							$error = \CCrmActivity::GetLastErrorMessage();
							if (empty($error))
							{
								$error = 'Deletion failed with activity #'.$activity['ID'];
							}
							$this->collectError(new Main\Error($error,self::ERROR_DELETION_FAILED));
							$this->incrementFailCount();
						}
					}
				}
				else
				{
					$this->collectError(new Main\Error('Access denied to activity #'.$activity['ID'], self::ERROR_PERMISSION_DENIED));
					$this->incrementFailCount();
				}

				if ($this->hasTimeLimitReached())
				{
					$success = false;
					break;
				}
			}
		}

		return $success;
	}

	/**
	 * Returns count of entities.
	 *
	 * @return int
	 */
	public function countEntityWithFile()
	{
		$count = -1;

		$query = $this->prepareQuery();

		if ($this->prepareFilter($query))
		{
			$count = 0;

			$query
				//->where('TYPE_ID', '=', \CCrmActivityType::Email)
				->registerRuntimeField(new ORM\Fields\ExpressionField('CNT', 'COUNT(%s)', 'ID'))
				->registerRuntimeField(new ORM\Fields\ExpressionField('CNTFL', 'IFNULL(%s,0) + IFNULL(%s,0)', ['FILE.FILE_COUNT', 'DISK_FILE.DISK_COUNT']))
				->addSelect('CNT')
				->addFilter('>CNTFL', 0);

			$res = $query->exec();
			if ($row = $res->fetch())
			{
				$count = $row['CNT'];
			}
		}

		return $count;
	}
}