| Current Path : /var/www/html/plugins/system/osmembershipupdatestatus/src/Extension/ |
| Current File : /var/www/html/plugins/system/osmembershipupdatestatus/src/Extension/UpdateSubscriptionsStatus.php |
<?php
/**
* @package Joomla
* @subpackage Membership Pro
* @author Tuan Pham Ngoc
* @copyright Copyright (C) 2012 - 2026 Ossolution Team
* @license GNU/GPL, see LICENSE.php
*/
namespace JoomDonation\MembershipPro\Plugin\System\UpdateSubscriptionsStatus\Extension;
use Joomla\CMS\Cache\Cache;
use Joomla\CMS\Component\ComponentHelper;
use Joomla\CMS\Plugin\CMSPlugin;
use Joomla\CMS\Plugin\PluginHelper;
use Joomla\Database\DatabaseAwareTrait;
use Joomla\Event\DispatcherInterface;
use Joomla\Event\Event;
use Joomla\Event\SubscriberInterface;
use OSSolution\MembershipPro\Admin\Event\Subscription\MembershipExpire;
defined('_JEXEC') or die;
class UpdateSubscriptionsStatus extends CMSPlugin implements SubscriberInterface
{
use DatabaseAwareTrait;
public static function getSubscribedEvents(): array
{
return [
'onAfterRespond' => 'onAfterRespond',
];
}
/**
* Constructor.
*
* @param DispatcherInterface $dispatcher The dispatcher
* @param array $config An optional associative array of configuration settings
*/
public function __construct(DispatcherInterface $dispatcher, array $config)
{
parent::__construct($dispatcher, $config);
}
/**
* Register listeners
*
* @return void
*/
public function registerListeners()
{
if (!ComponentHelper::isEnabled('com_osmembership'))
{
return;
}
parent::registerListeners();
}
/**
* Update status of subscriptions to expired if today date is greater than expired date
*
* @return void
*/
public function onAfterRespond(Event $event): void
{
if (!$this->canRun())
{
return;
}
//Store last run time
$db = $this->getDatabase();
$query = $db->getQuery(true);
if (!trim($this->params->get('secret_code', '')))
{
$this->params->set('last_run', time());
$params = $this->params->toString();
$query->update('#__extensions')
->set('params = ' . $db->quote($params))
->where('`element` = "osmembershipupdatestatus"')
->where('`folder` = "system"');
try
{
// Lock the tables to prevent multiple plugin executions causing a race condition
$db->lockTable('#__extensions');
}
catch (\Exception $e)
{
// If we can't lock the tables it's too risk continuing execution
return;
}
try
{
// Update the plugin parameters
$result = $db->setQuery($query)->execute();
$this->clearCacheGroups(['com_plugins'], [0, 1]);
}
catch (\Exception $exc)
{
// If we failed to execite
$db->unlockTables();
$result = false;
}
try
{
// Unlock the tables after writing
$db->unlockTables();
}
catch (\Exception $e)
{
// If we can't lock the tables assume we have somehow failed
$result = false;
}
// Abort on failure
if (!$result)
{
return;
}
}
// Require library + register autoloader
require_once JPATH_ADMINISTRATOR . '/components/com_osmembership/loader.php';
$config = \OSMembershipHelper::getConfig();
$query->clear()
->select('a.id')
->from('#__osmembership_subscribers AS a')
->innerJoin('#__osmembership_plans AS b ON a.plan_id = b.id')
->where('b.lifetime_membership != 1')
->where('a.published = 1')
->order('a.id');
$gracePeriod = (int) $config->get('grace_period');
if ($gracePeriod > 0)
{
$gracePeriodUnit = $config->get('grace_period_unit', 'd');
switch ($gracePeriodUnit)
{
case 'm':
$query->where('DATE_ADD(a.to_date, INTERVAL ' . $gracePeriod . ' MINUTE) < UTC_TIMESTAMP()');
break;
case 'h':
$query->where('DATE_ADD(a.to_date, INTERVAL ' . $gracePeriod . ' HOUR) < UTC_TIMESTAMP()');
break;
default:
$query->where('DATE_ADD(a.to_date, INTERVAL ' . $gracePeriod . ' DAY) < UTC_TIMESTAMP()');
break;
}
}
else
{
$query->where('a.to_date < UTC_TIMESTAMP()');
}
$db->setQuery($query, 0, 100);
$ids = $db->loadColumn();
if (count($ids) == 0)
{
return;
}
//Load Plugin to trigger OnMembershipExpire event
PluginHelper::importPlugin('osmembership');
$app = $this->getApplication();
foreach ($ids as $id)
{
$row = new \OSMembershipTableSubscriber($db);
if ($row->load($id))
{
$row->published = 2;
$row->store();
//Trigger plugins
$membershipExpireEvent = new MembershipExpire(['row' => $row]);
$app->getDispatcher()->dispatch($membershipExpireEvent->getName(), $membershipExpireEvent);
}
}
}
/**
* Method to check whether this plugin should be run
*
* @return bool
*/
private function canRun()
{
// If trigger reminder code is set, we will only process sending reminder from cron job
if (trim($this->params->get('secret_code', ''))
&& trim($this->params->get('secret_code', '')) != $this->getApplication()->getInput()->getString('secret_code'))
{
return false;
}
// We only need to check last run time if cron job is not used
if (!trim($this->params->get('secret_code', '')))
{
$lastRun = (int) $this->params->get('last_run', 0);
$now = time();
$cacheTime = (int) $this->params->get('cache_time', 1) * 3600;
if (($now - $lastRun) < $cacheTime)
{
return false;
}
}
return true;
}
/**
* Clears cache groups. We use it to clear the plugins cache after we update the last run timestamp.
*
* @param array $clearGroups The cache groups to clean
* @param array $cacheClients The cache clients (site, admin) to clean
*
* @return void
*
* @since 2.0.0
*/
private function clearCacheGroups(array $clearGroups, array $cacheClients = [0, 1])
{
$app = $this->getApplication();
foreach ($clearGroups as $group)
{
foreach ($cacheClients as $clientId)
{
try
{
$options = [
'defaultgroup' => $group,
'cachebase' => ($clientId) ? JPATH_ADMINISTRATOR . '/cache' :
$app->get('cache_path', JPATH_SITE . '/cache'),
];
$cache = Cache::getInstance('callback', $options);
$cache->clean();
}
catch (\Exception $e)
{
// Ignore it
}
}
}
}
}