Your IP : 216.73.217.142


Current Path : /var/www/consult-e-syn/public_html/plugins/ats/removeattachments/
Upload File :
Current File : /var/www/consult-e-syn/public_html/plugins/ats/removeattachments/removeattachments.php

<?php
/**
 * @package   ats
 * @copyright Copyright (c)2011-2022 Nicholas K. Dionysopoulos / Akeeba Ltd
 * @license   GNU General Public License version 3, or later
 */

defined('_JEXEC') or die();

use Akeeba\TicketSystem\Admin\Helper\Permissions;
use Akeeba\TicketSystem\Admin\Model\Attachments;
use FOF40\Container\Container;
use FOF40\Date\Date;
use FOF40\Timer\Timer;
use Joomla\CMS\Log\Log;
use Joomla\CMS\Plugin\CMSPlugin;

/**
 * Deletes the Manager Notes of tickets when they are closed or unpublished.
 *
 * @since 3.2.0
 */
class plgAtsRemoveattachments extends CMSPlugin
{
	const atsCommandName = 'removeattachments';

	/**
	 * @inheritDoc
	 */
	public function __construct(&$subject, $config = [])
	{
		parent::__construct($subject, $config);

		if (!defined('FOF40_INCLUDED') && !@include_once(JPATH_LIBRARIES . '/fof40/include.php'))
		{
			throw new RuntimeException('This extension requires FOF 4.', 500);
		}

		$this->loadLanguage();
	}

	/**
	 * Returns information about the CRON task provided by this plugin
	 *
	 * @return  array
	 *
	 * @since   3.2.0
	 */
	public function onAtsCronTaskInfo()
	{
		return [
			'command'     => self::atsCommandName,
			'label'       => 'PLG_ATS_' . $this->_name . '_TASK_LABEL',
			'description' => 'PLG_ATS_' . $this->_name . '_TASK_DESC',
		];
	}

	/**
	 * Handles the ATS CRON tasks.
	 *
	 * @param   string  $command  The command name ATS CRON was asked to execute.
	 * @param   array   $options  Any options passed to this CRON job
	 *
	 * @return  bool|null  True on success, null if it's not the expected command name.
	 * @since   3.2.0
	 */
	public function onAtsCronTask($command, array $options = [])
	{
		// Make sure we are calling the correct command
		if ($command != self::atsCommandName)
		{
			return null;
		}

		$timeLimit    = array_key_exists('time_limit', $options) ? $options['time_limit'] : 86400;
		$timer        = new Timer($timeLimit);
		$onlyClosed   = $this->params->get('only_closed', 1) == 1;
		$container    = Container::getInstance('com_ats');
		$totalDeleted = 0;

		$max_age = $this->params->get('maxattachmentage', 30);
		$until   = time() - $max_age * 3600 * 24;
		$jUntil  = new Date($until);

		// Loop while we have tickets and we have not hit the time limit
		while ($timer->getTimeLeft())
		{
			Log::add(sprintf("Getting up to 100 attachments%s", $onlyClosed ? ' of closed / disabled tickets' : ''), Log::DEBUG, 'ats.cron');

			/** @var Attachments $attachModel */
			$attachModel = $container->factory->model('Attachments')->tmpInstance();
			$attachModel->created_on([
				'method'   => 'search',
				'operator' => '<=',
				'value'    => $jUntil->toSql(),
			])
				->enabled(1)
				->with(['posts']);

			// Filter for enabled tickets when necessary
			if ($onlyClosed)
			{
				/**
				 * whereHas filters the relationship by manipulating the count query returned by the relationship class.
				 *
				 * Attachments have a 'hasOne' relationship to Posts. So what I do is filter by posts which belong to
				 * closed or unpublished tickets. Essentially I am doing a subquery to the #__ats_tickets table in the
				 * (sub)query to the #__ats_posts table. By using indexed columns this is pretty darned fast, even with
				 * hundreds of thousands of tickets.
				 */
				$attachModel->whereHas('post', function (JDatabaseQuery $q) {
					$sq = clone $q;
					$sq->clear()
						->select($sq->qn('ats_ticket_id'))
						->from($sq->qn('#__ats_tickets'))
						->where($sq->qn('status') . ' = ' . $sq->q('C'), 'OR')
						->where($sq->qn('enabled') . ' = 0', 'OR');

					$q->where($q->qn('ats_ticket_id') . ' IN (' . $sq . ')');

					return $q;
				});
			}

			$attachments = $attachModel->get(true, 0, 100);

			if ($attachments->count() == 0)
			{
				if ($totalDeleted)
				{
					Log::add(sprintf('Deleted a total of %d attachments', $totalDeleted), Log::INFO, 'ats.cron');
				}
				else
				{
					Log::add('No attachments to delete were found', Log::INFO, 'ats.cron');
				}

				return true;
			}

			Log::add(sprintf('Found %d attachments to process', $attachments->count()), Log::DEBUG, 'ats.cron');

			/** @var Attachments $item */
			$deleted = 0;

			foreach ($attachments as $item)
			{
				if ($timer->getTimeLeft() <= 0)
				{
					Log::add(sprintf('Deleted %d attachments in this batch', $deleted), Log::DEBUG, 'ats.cron');

					break 2;
				}

				Log::add(sprintf(
					'Deleting attachment #%d (%s) from ticket #%u "%s", post %d by %s',
					$item->getId(),
					$item->original_filename,
					$item->post->ticket->getId(),
					$item->post->ticket->title,
					$item->post->getId(),
					Permissions::getUser($item->post->created_by)->username
				), Log::INFO, 'ats.cron');
				$item->delete();

				$deleted++;
				$totalDeleted++;
			}

			Log::add(sprintf('Deleted %d attachments in this batch', $deleted), Log::DEBUG, 'ats.cron');
		}

		Log::add(sprintf('I have reached the time limit of %u second(s). Stopping for now.', $timeLimit), Log::DEBUG, 'ats.cron');
		Log::add(sprintf('Deleted a total of %d attachments. More attachments to delete exist (I ran out of time).', $totalDeleted), Log::INFO, 'ats.cron');

		return true;
	}
}