Файловый менеджер - Редактировать - /var/www/html/osmembership.zip
Ðазад
PK ! � � � ) limitsubscriptions/limitsubscriptions.xmlnu �[��� <?xml version="1.0" encoding="utf-8"?> <extension version="4.2.0" type="plugin" group="osmembership" method="upgrade"> <name>Membership Pro - Limit Subscriptions</name> <author>Tuan Pham Ngoc</author> <authorEmail>tuanpn@joomdonation.com</authorEmail> <authorUrl>https://joomdonation.com</authorUrl> <copyright>Copyright (C) 2012 - 2025 Ossolution Team</copyright> <license>GNU General Public License version 3, or later</license> <creationDate>July 2016</creationDate> <version>4.3.1</version> <description>This plugin allows you to limit maximum subscribers can subscribe for a subscription plan. When the number of subscribers reach the limit, the plan will be unpublished. </description> <files> <filename plugin="limitsubscriptions">limitsubscriptions.php</filename> <folder>tmpl</folder> </files> <languages folder="language"> <language tag="en-GB">en-GB/en-GB.plg_osmembership_limitsubscriptions.ini</language> </languages> <config> <fields name="params"> <fieldset name="basic"> <field name="show_on_frontend" type="radio" label="Show On Frontend" description="If set to Yes, this plugin will be available on frontend add/edit plan form" class="btn-group btn-group-yesno" default="0" > <option value="1">JYES</option> <option value="0">JNO</option> </field> </fieldset> </fields> </config> </extension> PK ! ��c� � limitsubscriptions/tmpl/form.phpnu �[��� <?php /** * @package Joomla * @subpackage Membership Pro * @author Tuan Pham Ngoc * @copyright Copyright (C) 2012 - 2025 Ossolution Team * @license GNU/GPL, see LICENSE.php */ defined('_JEXEC') or die; use Joomla\CMS\Language\Text; use Joomla\Registry\Registry; /** * Layout variables * ----------------- * @var OSMembershipTablePlan $row */ $params = new Registry($row->params); $maxSubscriptions = $params->get('max_subscriptions', ''); ?> <div class="control-group"> <div class="control-label"> <?php echo OSMembershipHelperHtml::getFieldLabel('max_subscriptions', Text::_('PLG_OSMEMBERSHIP_MAX_SUBSCRIPTIONS'), Text::_('PLG_OSMEMBERSHIP_MAX_SUBSCRIPTIONS_EXPLAIN')); ?> </div> <div class="controls"> <input type="text" class="form-control input-small" name="max_subscriptions" value="<?php echo $maxSubscriptions; ?>"/> </div> </div> PK ! u�� � ) limitsubscriptions/limitsubscriptions.phpnu �[��� <?php /** * @package Joomla * @subpackage Membership Pro * @author Tuan Pham Ngoc * @copyright Copyright (C) 2012 - 2025 Ossolution Team * @license GNU/GPL, see LICENSE.php */ defined('_JEXEC') or die; use Joomla\CMS\Application\CMSApplication; use Joomla\CMS\Language\Text; use Joomla\CMS\Plugin\CMSPlugin; use Joomla\CMS\Plugin\PluginHelper; use Joomla\Database\DatabaseDriver; use Joomla\Event\Event; use Joomla\Event\SubscriberInterface; use Joomla\Registry\Registry; class plgOSMembershipLimitSubscriptions extends CMSPlugin implements SubscriberInterface { use MPFEventResult; /** * Application object. * * @var CMSApplication */ protected $app; /** * Database object. * * @var DatabaseDriver */ protected $db; public static function getSubscribedEvents(): array { return [ 'onEditSubscriptionPlan' => 'onEditSubscriptionPlan', 'onAfterSaveSubscriptionPlan' => 'onAfterSaveSubscriptionPlan', 'onMembershipActive' => 'onMembershipActive', ]; } /** * Render setting form * * @param Event $event * * @return void */ public function onEditSubscriptionPlan(Event $event): void { /* @var OSMembershipTablePlan $row */ [$row] = array_values($event->getArguments()); if (!$this->isExecutable()) { return; } ob_start(); $this->loadLanguage(); $this->drawSettingForm($row); $form = ob_get_clean(); $result = [ 'title' => Text::_('PLG_OSMEMBERSHIP_MAX_SUBCRIPTIONS_SETTING'), 'form' => $form, ]; $this->addResult($event, $result); } /** * Store setting into database, in this case, use params field of plans table * * @param Event $event * * @return void */ public function onAfterSaveSubscriptionPlan(Event $event): void { /** * @var string $context * @var OSMembershipTablePlan $row * @var array $data * @var $isNew */ [$context, $row, $data, $isNew] = array_values($event->getArguments()); if (!$this->isExecutable()) { return; } $params = new Registry($row->params); $params->set('max_subscriptions', $data['max_subscriptions']); $row->params = $params->toString(); $row->store(); } /** * @param Event $event * * @return void */ public function onMembershipActive(Event $event): void { /* @var OSMembershipTableSubscriber $row */ [$row] = array_values($event->getArguments()); $plan = new OSMembershipTablePlan($this->db); $plan->load($row->plan_id); $params = new Registry($plan->params); $maxSubscriptions = (int) $params->get('max_subscriptions', 0); if (!$maxSubscriptions) { return; } $db = $this->db; $query = $db->getQuery(true); $query->select('COUNT(id)') ->from('#__osmembership_subscribers') ->where('plan_id = ' . (int) $row->plan_id) ->where('published IN (1,2)'); $db->setQuery($query); $total = $db->loadResult(); if ($total >= $maxSubscriptions) { $plan->published = 0; $plan->store(); } } /** * Method to check if the plugin is executable * * @return bool */ private function isExecutable() { if ($this->app->isClient('site') && !$this->params->get('show_on_frontend')) { return false; } return true; } /** * Display form allows users to change settings on subscription plan add/edit screen * * @param OSMembershipTablePlan $row */ private function drawSettingForm($row) { require PluginHelper::getLayoutPath($this->_type, $this->_name, 'form'); } } PK ! =W5d d ! ticketshistory/ticketshistory.xmlnu �[��� <?xml version="1.0" encoding="utf-8"?> <extension version="4.2.0" type="plugin" group="osmembership" method="upgrade"> <name>Membership Pro - Helpdesk Pro Tickets History</name> <author>Tuan Pham Ngoc</author> <authorEmail>tuanpn@joomdonation.com</authorEmail> <authorUrl>https://joomdonation.com</authorUrl> <copyright>Copyright (C) 2012 - 2025 Ossolution Team</copyright> <license>GNU General Public License version 3, or later</license> <creationDate>Feb 2019</creationDate> <version>4.3.1</version> <description>This plugin display Tickets History of the current user in his Membership Pro user profile </description> <files> <filename plugin="ticketshistory">ticketshistory.php</filename> <folder>tmpl</folder> </files> <config> <fields name="params"> <fieldset name="basic"> <field name="number_tickets" type="number" filter="integer" label="Number Tickets" description="Number of tickets displayed on the plugin" default="20" /> <field name="show_created_date" type="radio" label="Show Created Date" class="btn-group btn-group-yesno" default="1" > <option value="1">JYES</option> <option value="0">JNO</option> </field> <field name="show_modified_date" type="radio" label="Show Modified Date" class="btn-group btn-group-yesno" default="1" > <option value="1">JYES</option> <option value="0">JNO</option> </field> <field name="show_status" type="radio" label="Show Status" class="btn-group btn-group-yesno" default="1" > <option value="1">JYES</option> <option value="0">JNO</option> </field> <field name="show_priority" type="radio" label="Show Priority" class="btn-group btn-group-yesno" default="1" > <option value="1">JYES</option> <option value="0">JNO</option> </field> </fieldset> </fields> </config> </extension>PK ! �� ticketshistory/tmpl/default.phpnu �[��� <?php /** * @package Joomla * @subpackage Membership Pro * @author Tuan Pham Ngoc * @copyright Copyright (C) 2012 - 2025 Ossolution Team * @license GNU/GPL, see LICENSE.php */ defined('_JEXEC') or die; use Joomla\CMS\HTML\HTMLHelper; use Joomla\CMS\Language\Text; use Joomla\CMS\Router\Route; use OSSolution\HelpdeskPro\Site\Helper\Route as RouteHelper; use OSSolution\HelpdeskPro\Site\Helper\Helper as HelpdeskProHelper; /** * Layout variables * * @var array $rows * @var array $statusList * @var array $priorityList */ $bootstrapHelper = OSMembershipHelperBootstrap::getInstance(); $hiddenPhoneClass = $bootstrapHelper->getClassMapping('hidden-phone'); $centerClass = $bootstrapHelper->getClassMapping('center'); $btnDanger = $bootstrapHelper->getClassMapping('btn btn-danger'); $config = HelpdeskProHelper::getConfig(); HelpdeskProHelper::loadLanguage(); ?> <table class="osm-hdp-tickets-history <?php echo $bootstrapHelper->getClassMapping('table table-striped table-bordered'); ?> osm-responsive-table"> <thead> <tr> <th style="text-align: left;"> <?php echo Text::_('HDP_TITLE'); ?> </th> <?php if ($this->params->get('show_created_date', 1)) { ?> <th class="<?php echo $centerClass; ?>"> <?php echo Text::_('HDP_CREATED_DATE'); ?> </th> <?php } if ($this->params->get('show_modified_date', 1)) { ?> <th class="<?php echo $centerClass; ?>"> <?php echo Text::_('HDP_MODIFIED_DATE'); ?> </th> <?php } if (isset($lists['filter_status_id']) && $this->params->get('show_status', 1)) { ?> <th width="8%"> <?php echo Text::_('HDP_STATUS'); ?> </th> <?php } if (isset($lists['filter_priority_id']) && $this->params->get('show_priority', 1)) { ?> <th width="8%"> <?php echo Text::_('HDP_PRIORITY'); ?> </th> <?php } ?> <th width="2%" class="<?php echo $centerClass; ?>"> <?php echo Text::_('HDP_ID'); ?> </th> </tr> </thead> <tbody> <?php $k = 0; foreach ($rows as $row) { $link = Route::_(RouteHelper::getTicketRoute($row->id), false); ?> <tr class="<?php echo "row$k"; ?> hdp-ticket-status-<?php echo $row->status_id; ?>"> <td> <a href="<?php echo $link; ?>"><?php echo $row->subject; ?></a> <?php if ($this->params->get('show_category', 1)) { ?> <br /> <small><?php echo Text::_('HDP_CATEGORY'); ?>: <strong><?php echo $row->category_title ; ?></strong></small> <?php } ?> </td> <?php if ($this->params->get('show_created_date', 1)) { ?> <td class="<?php echo $centerClass; ?>"> <?php echo HTMLHelper::_('date', $row->created_date, $config->date_format); ?> </td> <?php } if ($this->params->get('show_modified_date', 1)) { ?> <td class="<?php echo $centerClass; ?>"> <?php echo HTMLHelper::_('date', $row->modified_date, $config->date_format); ?> </td> <?php } if (count($statusList) && $this->params->get('show_status', 1)) { ?> <td> <?php echo $statusList[$row->status_id] ?? ''; ?> </td> <?php } if (count($priorityList) && $this->params->get('show_priority', 1)) { ?> <td> <?php echo $priorityList[$row->priority_id] ?? ''; ?> </td> <?php } ?> <td class="<?php echo $centerClass; ?>"> <?php echo $row->id; ?> </td> </tr> <?php $k = 1 - $k; } ?> </tbody> </table> PK ! ���P� � ! ticketshistory/ticketshistory.phpnu �[��� <?php /** * @package Joomla * @subpackage Membership Pro * @author Tuan Pham Ngoc * @copyright Copyright (C) 2012 - 2025 Ossolution Team * @license GNU/GPL, see LICENSE.php */ defined('_JEXEC') or die; use Joomla\CMS\Application\CMSApplication; use Joomla\CMS\Component\ComponentHelper; use Joomla\CMS\Language\Text; use Joomla\CMS\Plugin\CMSPlugin; use Joomla\CMS\Plugin\PluginHelper; use Joomla\Database\DatabaseDriver; use Joomla\Event\Event; use Joomla\Event\SubscriberInterface; use OSL\Container\Container; use OSSolution\HelpdeskPro\Site\Helper\Database as HelpdeskproHelperDatabase; use OSSolution\HelpdeskPro\Site\Helper\Helper as HelpdeskproHelper; class plgOSMembershipTicketsHistory extends CMSPlugin implements SubscriberInterface { use MPFEventResult; /** * Application object. * * @var CMSApplication */ protected $app; /** * Database object. * * @var DatabaseDriver */ protected $db; public static function getSubscribedEvents(): array { return [ 'onProfileDisplay' => 'onProfileDisplay', ]; } /** * Render setting form * * @param Event $event * * @return void */ public function onProfileDisplay(Event $event): void { /* @var OSMembershipTableSubscriber $row */ [$row] = array_values($event->getArguments()); ob_start(); $this->drawTicketsHistory($row); $result = [ 'title' => Text::_('OSM_HDP_TICKETS_HISTORY'), 'form' => ob_get_clean(), ]; $this->addResult($event, $result); } /** * Register listeners * * @return void */ public function registerListeners() { if (!ComponentHelper::isEnabled('com_helpdeskpro')) { return; } if ($this->app->isClient('administrator')) { return; } parent::registerListeners(); } /** * Display tickets history of the current logged in user * * @param OSMembershipTableSubscriber $row */ private function drawTicketsHistory($row) { // Bootstrap the component $db = $this->db; $query = $db->getQuery(true) ->select('a.*, b.title AS category_title') ->from('#__helpdeskpro_tickets AS a') ->leftJoin('#__helpdeskpro_categories AS b ON a.category_id= b.id ') ->where('a.user_id = ' . $this->app->getIdentity()->id) ->order('id DESC'); $db->setQuery($query, 0, $this->params->get('number_tickets') ?: 20); $rows = $db->loadObjectList(); if (count($rows) === 0) { return; } // Bootstrap the component require_once JPATH_ADMINISTRATOR . '/components/com_helpdeskpro/init.php'; // Get component config data $config = require JPATH_ADMINISTRATOR . '/components/com_helpdeskpro/config.php'; // Creating component container, register auto-loader $container = Container::getInstance('com_helpdeskpro', $config); $fieldSuffix = HelpdeskproHelper::getFieldSuffix(); // Ticket status filter $rowStatuses = HelpdeskproHelperDatabase::getAllStatuses('ordering', $fieldSuffix); $statusList = []; foreach ($rowStatuses as $status) { $statusList[$status->id] = $status->title; } // Ticket priority filter $rowPriorities = HelpdeskproHelperDatabase::getAllPriorities('ordering', $fieldSuffix); $priorityList = []; foreach ($rowPriorities as $priority) { $priorityList[$priority->id] = $priority->title; } require PluginHelper::getLayoutPath('osmembership', 'ticketshistory', 'default'); } } PK ! ?��! ! usercoupons/usercoupons.phpnu �[��� <?php /** * @package Joomla * @subpackage Membership Pro * @author Tuan Pham Ngoc * @copyright Copyright (C) 2012 - 2025 Ossolution Team * @license GNU/GPL, see LICENSE.php */ defined('_JEXEC') or die; use Joomla\CMS\Application\CMSApplication; use Joomla\CMS\Language\Text; use Joomla\CMS\Plugin\CMSPlugin; use Joomla\CMS\Plugin\PluginHelper; use Joomla\Database\DatabaseDriver; use Joomla\Event\Event; use Joomla\Event\SubscriberInterface; class plgOSMembershipUserCoupons extends CMSPlugin implements SubscriberInterface { use MPFEventResult; /** * Application object. * * @var CMSApplication */ protected $app; /** * Database object. * * @var DatabaseDriver */ protected $db; /** * Get list of subscriber * @return string[] */ public static function getSubscribedEvents(): array { return [ 'onProfileDisplay' => 'onProfileDisplay', ]; } /** * Render setting form * * @param Event $event * * @return void */ public function onProfileDisplay(Event $event): void { /* @var OSMembershipTableSubscriber $row */ [$row] = array_values($event->getArguments()); ob_start(); $this->drawUserCoupons($row); $result = [ 'title' => Text::_('OSM_USER_COUPONS'), 'form' => ob_get_clean(), ]; $this->addResult($event, $result); } /** * Display registration history of the current logged in user * * @param OSMembershipTableSubscriber $row */ private function drawUserCoupons($row) { $db = $this->db; $query = $db->getQuery(true) ->select('*') ->from('#__osmembership_coupons') ->where('user_id = ' . $row->user_id) ->where('published = 1') ->order('id DESC'); $db->setQuery($query); $rows = $db->loadObjectList(); if ($rows === []) { return; } $config = OSMembershipHelper::getConfig(); require PluginHelper::getLayoutPath('osmembership', 'usercoupons', 'default'); } } PK ! ����A A usercoupons/tmpl/default.phpnu �[��� <?php /** * @package Joomla * @subpackage Membership Pro * @author Tuan Pham Ngoc * @copyright Copyright (C) 2012 - 2025 Ossolution Team * @license GNU/GPL, see LICENSE.php */ defined('_JEXEC') or die; use Joomla\CMS\Language\Text; use Joomla\CMS\HTML\HTMLHelper; /** * Layout variables * ----------------- * @var array $rows * @var MPFConfig $config */ $bootstrapHelper = OSMembershipHelperBootstrap::getInstance(); $centerClass = $bootstrapHelper->getClassMapping('center'); $discountTypes = [ 0 => '%', 1 => $config->get('currency_symbol', '$') ]; ?> <table class="adminlist <?php echo $bootstrapHelper->getClassMapping('table table-striped table-bordered'); ?>" id="adminForm"> <thead> <tr> <th class="title" style="text-align: left;"> <?php echo Text::_('OSM_CODE'); ?> </th> <th class="center title"> <?php echo Text::_('OSM_DISCOUNT'); ?> </th> <?php if ($this->params->get('show_times', 1)) { ?> <th class="center title"> <?php echo Text::_('OSM_TIMES'); ?> </th> <?php } if ($this->params->get('show_used', 1)) { ?> <th class="center title"> <?php echo Text::_('OSM_USED'); ?> </th> <?php } if ($this->params->get('show_valid_from', 1)) { ?> <th class="center title"> <?php echo Text::_('OSM_VALID_FROM'); ?> </th> <?php } if ($this->params->get('show_valid_to', 1)) { ?> <th class="center title"> <?php echo Text::_('OSM_VALID_TO'); ?> </th> <?php } ?> </tr> </thead> <tbody> <?php $k = 0; foreach ($rows as $row) { ?> <tr class="<?php echo "row$k"; ?>"> <td> <?php echo $row->code; ?> </td> <td class="center"> <?php echo OSMembershipHelper::formatAmount($row->discount, $config) . ($discountTypes[$row->coupon_type] ?? ''); ?> </td> <?php if ($this->params->get('show_times', 1)) { ?> <td class="center"> <?php echo $row->times; ?> </td> <?php } if ($this->params->get('show_used', 1)) { ?> <td class="center"> <?php echo $row->used; ?> </td> <?php } if ($this->params->get('show_valid_from', 1)) { ?> <td class="center"> <?php if ((int) $row->valid_from) { echo HTMLHelper::_('date', $row->valid_from, $config->date_format, null); } ?> </td> <?php } if ($this->params->get('show_valid_to', 1)) { ?> <td class="center"> <?php if ((int) $row->valid_to) { echo HTMLHelper::_('date', $row->valid_to, $config->date_format, null); } ?> </td> <?php } ?> </tr> <?php $k = 1 - $k; } ?> </tbody> </table>PK ! M�T� � usercoupons/usercoupons.xmlnu �[��� <?xml version="1.0" encoding="utf-8"?> <extension version="4.2.0" type="plugin" group="osmembership" method="upgrade"> <name>Membership Pro - User's Coupons</name> <author>Tuan Pham Ngoc</author> <authorEmail>tuanpn@joomdonation.com</authorEmail> <authorUrl>https://joomdonation.com</authorUrl> <copyright>Copyright (C) 2012 - 2025 Ossolution Team</copyright> <license>GNU General Public License version 3, or later</license> <creationDate>Feb 2019</creationDate> <version>4.3.1</version> <description>This plugin displays coupon available for the current user in his profile</description> <files> <filename plugin="usercoupons">usercoupons.php</filename> <folder>tmpl</folder> </files> <config> <fields name="params"> <fieldset name="basic"> <field name="show_times" type="radio" label="Show Times Column" class="btn-group btn-group-yesno" default="1" > <option value="1">JYES</option> <option value="0">JNO</option> </field> <field name="show_used" type="radio" label="Show Used Column" class="btn-group btn-group-yesno" default="1" > <option value="1">JYES</option> <option value="0">JNO</option> </field> <field name="show_valid_from" type="radio" label="Show Valid From Column" class="btn-group btn-group-yesno" default="1" > <option value="1">JYES</option> <option value="0">JNO</option> </field> <field name="show_valid_to" type="radio" label="Show Valid To Column" class="btn-group btn-group-yesno" default="1" > <option value="1">JYES</option> <option value="0">JNO</option> </field> </fieldset> </fields> </config> </extension>PK ! FL�+| | fields/fields.phpnu �[��� <?php /** * @package Joomla * @subpackage Membership Pro * @author Tuan Pham Ngoc * @copyright Copyright (C) 2012 - 2025 Ossolution Team * @license GNU/GPL, see LICENSE.php */ defined('_JEXEC') or die; use Joomla\CMS\Language\Text; use Joomla\CMS\Plugin\CMSPlugin; use Joomla\Event\Event; use Joomla\Event\SubscriberInterface; class plgOSMembershipFields extends CMSPlugin implements SubscriberInterface { use MPFEventResult; /** * Application object. * * @var \Joomla\CMS\Application\CMSApplication */ protected $app; /** * Database object. * * @var \Joomla\Database\DatabaseDriver */ protected $db; public static function getSubscribedEvents(): array { return [ 'onEditSubscriptionPlan' => 'onEditSubscriptionPlan', 'onAfterSaveSubscriptionPlan' => 'onAfterSaveSubscriptionPlan', ]; } /** * Render setting form * * @param Event $event * * @return void */ public function onEditSubscriptionPlan(Event $event): void { /* @var OSMembershipTablePlan $row */ [$row] = array_values($event->getArguments()); if (!$this->isExecutable()) { return; } ob_start(); $this->loadLanguage(); $this->drawSettingForm($row); $result = [ 'title' => Text::_('OSM_FIELDS_ASSIGNMENT'), 'form' => ob_get_clean(), ]; $this->addResult($event, $result); } /** * Store setting into database, in this case, use params field of plans table * * @param Event $event * * @return void */ public function onAfterSaveSubscriptionPlan(Event $event): void { /** * @var string $context * @var OSMembershipTablePlan $row * @var array $data * @var $isNew */ [$context, $row, $data, $isNew] = array_values($event->getArguments()); if (!$this->isExecutable()) { return; } $db = $this->db; $query = $db->getQuery(true); $formFields = $data['subscription_form_fields'] ?? []; $formFields = array_filter($formFields); if (!$isNew) { $query->delete('#__osmembership_field_plan') ->where('plan_id = ' . $row->id); $db->setQuery($query) ->execute(); } if (!count($formFields)) { return; } $query->clear() ->insert('#__osmembership_field_plan') ->columns($this->db->quoteName(['field_id', 'plan_id'])); foreach ($formFields as $field) { $query->values(implode(',', $db->quote([$field, $row->id]))); } $db->setQuery($query) ->execute(); } /** * Method to check if the plugin is executable * * @return bool */ private function isExecutable() { if ($this->app->isClient('site') && !$this->params->get('show_on_frontend')) { return false; } return true; } /** * Display form allows users to change settings on subscription plan add/edit screen * * @param OSMembershipTablePlan $row */ private function drawSettingForm($row) { $db = $this->db; $query = $db->getQuery(true) ->select('id, plan_id, name, title') ->from('#__osmembership_fields') ->where('published = 1') ->order('plan_id, ordering'); $db->setQuery($query); $rowFields = $db->loadObjectList(); $selectedFieldIds = []; // Load assigned fields for this event if ($row->id) { $query->clear() ->select('field_id') ->from('#__osmembership_field_plan') ->where('plan_id = ' . $row->id); $db->setQuery($query); $selectedFieldIds = $db->loadColumn(); } $count = 0; $bootstrapHelper = OSMembershipHelperBootstrap::getInstance(); $rowFluid = $bootstrapHelper->getClassMapping('row-fluid'); $spanClass = $bootstrapHelper->getClassMapping('span3'); ?> <div class="<?php echo $rowFluid; ?>"> <?php foreach ($rowFields as $rowField) { $count++; $attributes = []; if ($rowField->plan_id == 0 || $rowField->name == 'email') { $attributes[] = 'disabled'; $attributes[] = 'checked'; } elseif (in_array($rowField->id, $selectedFieldIds)) { $attributes[] = 'checked'; } ?> <div class="<?php echo $spanClass; ?>"> <label class="checkbox"> <input type="checkbox" value="<?php echo $rowField->id ?>" name="subscription_form_fields[]"<?php if (count($attributes)) { echo ' ' . implode(' ', $attributes); } ?>><?php echo '[' . $rowField->id . '] - ' . $rowField->title; ?> </label> </div> <?php } ?> </div> <?php } } PK ! 뛼o� � fields/fields.xmlnu �[��� <?xml version="1.0" encoding="utf-8"?> <extension version="4.2.0" type="plugin" group="osmembership" method="upgrade"> <name>Membership Pro - Fields Assignment</name> <author>Tuan Pham Ngoc</author> <creationDate>October 2019</creationDate> <copyright>Copyright (C) 2012 - 2025 Ossolution Team</copyright> <license>http://www.gnu.org/licenses/gpl-2.0.html GNU/GPL</license> <authorEmail>services@joomdonation.com</authorEmail> <authorUrl>www.joomdonation.com</authorUrl> <version>4.3.1</version> <description>This plugin allows assigning custom fields to plans.</description> <files> <filename plugin="fields">fields.php</filename> </files> <languages folder="language"> <language tag="en-GB">en-GB/en-GB.plg_osmembership_fields.ini</language> </languages> <config> <fields name="params"> <fieldset name="basic"> <field name="show_on_frontend" type="radio" label="Show On Frontend" description="If set to Yes, this plugin will be available on frontend add/edit plan form" class="btn-group btn-group-yesno" default="0" > <option value="1">JYES</option> <option value="0">JNO</option> </field> </fieldset> </fields> </config> </extension> PK ! �e� � deleteaccount/deleteaccount.xmlnu �[��� <?xml version="1.0" encoding="utf-8"?> <extension version="4.2.0" type="plugin" group="osmembership" method="upgrade"> <name>Membership Pro - Delete User Account</name> <author>Tuan Pham Ngoc</author> <authorEmail>tuanpn@joomdonation.com</authorEmail> <authorUrl>https://joomdonation.com</authorUrl> <copyright>Copyright (C) 2012 - 2025 Ossolution Team</copyright> <license>GNU General Public License version 3, or later</license> <creationDate>Nov 2012</creationDate> <version>4.3.1</version> <description>This plugin is used to delete user account of a user when his last subscription record is deleted</description> <files> <filename plugin="deleteaccount">deleteaccount.php</filename> </files> <config> <fields name="params"> <fieldset name="basic"> <field name="exclude_user_groups" type="usergrouplist" layout="joomla.form.field.list-fancy-select" default="3,4,5,6,7,8" label="Exclude User Groups" multiple="true" description="Users from the selected user groups here won't be deleted even if all of his subscription records are deleted" /> </fieldset> </fields> </config> </extension> PK ! f�6 deleteaccount/deleteaccount.phpnu �[��� <?php /** * @package Joomla * @subpackage Membership Pro * @author Tuan Pham Ngoc * @copyright Copyright (C) 2012 - 2025 Ossolution Team * @license GNU/GPL, see LICENSE.php */ defined('_JEXEC') or die; use Joomla\CMS\Factory; use Joomla\CMS\Plugin\CMSPlugin; use Joomla\Event\Event; use Joomla\Event\SubscriberInterface; class plgOSMembershipDeleteAccount extends CMSPlugin implements SubscriberInterface { /** * Application object. * * @var \Joomla\CMS\Application\CMSApplication */ protected $app; /** * Database object. * * @var \Joomla\Database\DatabaseDriver */ protected $db; public static function getSubscribedEvents(): array { return [ 'onSubscriptionAfterDelete' => 'onSubscriptionAfterDelete', ]; } /** * Recalculate some important subscription information when a subscription record is being deleted * * @param Event $event * * @return void */ public function onSubscriptionAfterDelete(Event $event): void { /** * @var string $context * @var OSMembershipTableSubscriber $row */ [$context, $row] = array_values($event->getArguments()); if (!$row->user_id) { return; } $db = $this->db; $query = $db->getQuery(true) ->select('COUNT(*)') ->from('#__osmembership_subscribers') ->where('user_id = ' . $row->user_id) ->where('(published >= 1 OR payment_method LIKE "os_offline%")'); $db->setQuery($query); // No subscription records left if (!$db->loadResult()) { $user = Factory::getUser($row->user_id); $excludeUserGroups = $this->params->get('exclude_user_groups', [3, 4, 5, 6, 7, 8]); if (is_string($excludeUserGroups)) { $excludeUserGroups = explode(',', $excludeUserGroups); } $excludeUserGroups = array_unique(array_merge($excludeUserGroups, [7, 8])); if ($user->id && count(array_intersect($user->groups, $excludeUserGroups)) === 0) { // Delete the user account $user->delete(); // Delete the remaining orphans records $query->clear() ->delete('#__osmembership_subscribers') ->where('user_id = ' . $user->id); $db->setQuery($query) ->execute(); } } } } PK ! x���� � + subscriptioncontrol/subscriptioncontrol.phpnu �[��� <?php /** * @package Joomla * @subpackage Membership Pro * @author Tuan Pham Ngoc * @copyright Copyright (C) 2012 - 2025 Ossolution Team * @license GNU/GPL, see LICENSE.php */ defined('_JEXEC') or die; use Joomla\CMS\Application\CMSApplication; use Joomla\CMS\Factory; use Joomla\CMS\HTML\HTMLHelper; use Joomla\CMS\Language\Text; use Joomla\CMS\Plugin\CMSPlugin; use Joomla\CMS\Plugin\PluginHelper; use Joomla\Database\DatabaseDriver; use Joomla\Event\Event; use Joomla\Event\SubscriberInterface; use Joomla\Registry\Registry; use Joomla\Utilities\ArrayHelper; use OSSolution\MembershipPro\Admin\Event\Subscription\MembershipExpire; class plgOSMembershipSubscriptionControl extends CMSPlugin implements SubscriberInterface { use MPFEventResult; /** * Application object. * * @var CMSApplication */ protected $app; /** * Database object. * * @var DatabaseDriver */ protected $db; public static function getSubscribedEvents(): array { return [ 'onEditSubscriptionPlan' => 'onEditSubscriptionPlan', 'onAfterSaveSubscriptionPlan' => 'onAfterSaveSubscriptionPlan', 'onMembershipActive' => 'onMembershipActive', 'onMembershipExpire' => 'onMembershipExpire', ]; } /** * Render settings from * * @param Event $event * * @return void */ public function onEditSubscriptionPlan(Event $event): void { /* @var OSMembershipTablePlan $row */ [$row] = array_values($event->getArguments()); if (!$this->isExecutable()) { return; } ob_start(); $this->loadLanguage(); $this->drawSettingForm($row); $form = ob_get_contents(); ob_end_clean(); $result = [ 'title' => Text::_('PLG_OSMEMBERSHIP_SUBSCRIPTION_CONTROL_SETTINGS'), 'form' => $form, ]; $this->addResult($event, $result); } /** * Store setting into database * * @param Event $event * * @return void */ public function onAfterSaveSubscriptionPlan(Event $event): void { /** * @var string $context * @var OSMembershipTablePlan $row * @var array $data * @var $isNew */ [$context, $row, $data, $isNew] = array_values($event->getArguments()); if (!$this->isExecutable()) { return; } $params = new Registry($row->params); $keys = ['expiring_plan_ids', 'subscription_expired_subscribe_plan_ids']; foreach ($keys as $key) { $params->set($key, implode(',', $data[$key] ?? [])); } $row->params = $params->toString(); $row->store(); } /** * Run when a membership activated * * @param Event $event * * @return void */ public function onMembershipActive(Event $event): void { /* @var OSMembershipTableSubscriber $row */ [$row] = array_values($event->getArguments()); if (!$row->user_id) { return; } $plan = new OSMembershipTablePlan($this->db); $plan->load($row->plan_id); $params = new Registry($plan->params); $expiringPlanIds = array_filter(ArrayHelper::toInteger(explode(',', $params->get('expiring_plan_ids', '')))); if (count($expiringPlanIds) === 0) { return; } // Find all active and pending subscriptions of the current user for these plans and expiring it $db = $this->db; $query = $db->getQuery(true) ->select('id') ->from('#__osmembership_subscribers') ->where('published IN (0, 1)') ->where('user_id = ' . $row->user_id) ->whereIn('plan_id', $expiringPlanIds); $db->setQuery($query); $ids = $db->loadColumn(); if (count($ids) === 0) { return; } PluginHelper::importPlugin('osmembership'); $app = Factory::getApplication(); $rowSubscription = new OSMembershipTableSubscriber($db); $now = Factory::getDate()->toSql(); // Extra reminders $extraReminderSentFields = [ 'fourth_reminder_sent', 'fifth_reminder_sent', 'sixth_reminder_sent', ]; foreach ($ids as $id) { $rowSubscription->load($id); $rowSubscription->to_date = $now; $rowSubscription->published = 2; $rowSubscription->first_reminder_sent = 1; $rowSubscription->second_reminder_sent = 1; $rowSubscription->third_reminder_sent = 1; foreach ($extraReminderSentFields as $extraField) { if (property_exists($rowSubscription, $extraField)) { $rowSubscription->{$extraField} = 1; } } $rowSubscription->store(); $event = new MembershipExpire(['row' => $rowSubscription]); //Trigger plugins $app->triggerEvent($event->getName(), $event); } } /** * Run when a membership expiried die * * @param Event $event * * @return void */ public function onMembershipExpire(Event $event): void { /* @var OSMembershipTableSubscriber $row */ [$row] = array_values($event->getArguments()); if (!$row->user_id) { return; } $activePlans = OSMembershipHelperSubscription::getActiveMembershipPlans($row->user_id, [$row->id]); // There are still other active subscriptions of this plan, no need to process subscribing if (in_array($row->plan_id, $activePlans)) { return; } $plan = new OSMembershipTablePlan($this->db); $plan->load($row->plan_id); $params = new Registry($plan->params); $subscribePlanIds = array_filter( ArrayHelper::toInteger(explode(',', $params->get('subscription_expired_subscribe_plan_ids', ''))) ); if (count($subscribePlanIds) === 0) { return; } // Get data of the current subscription /* @var OSMembershipModelApi $model */ $model = MPFModel::getTempInstance('Api', 'OSMembershipModel'); $data = $model->getSubscriptionData($row->id); foreach ($subscribePlanIds as $planId) { $subscriptionData = $data; $subscriptionData['plan_id'] = $planId; $subscriptionData['user_id'] = $row->user_id; unset($subscriptionData['act']); try { $model->store($subscriptionData); } catch (Exception $e) { } } } /** * Method to check if the plugin is executable * * @return bool */ private function isExecutable() { if ($this->app->isClient('site') && !$this->params->get('show_on_frontend')) { return false; } return true; } /** * Display form allows users to change setting for this subscription plan * * @param OSMembershipTablePlan $row */ private function drawSettingForm($row) { $db = $this->db; $query = $db->getQuery(true) ->select('*') ->from('#__osmembership_plans') ->where('published = 1') ->order('ordering'); $db->setQuery($query); $options = []; foreach ($db->loadObjectList() as $plan) { $options[] = HTMLHelper::_('select.option', $plan->id, $plan->title); } require PluginHelper::getLayoutPath($this->_type, $this->_name, 'form'); } } PK ! �]�� � + subscriptioncontrol/subscriptioncontrol.xmlnu �[��� <?xml version="1.0" encoding="utf-8"?> <extension version="4.2.0" type="plugin" group="osmembership" method="upgrade"> <name>Membership Pro - Subscription Control</name> <author>Tuan Pham Ngoc</author> <authorEmail>tuanpn@joomdonation.com</authorEmail> <authorUrl>https://joomdonation.com</authorUrl> <copyright>Copyright (C) 2012 - 2025 Ossolution Team</copyright> <license>GNU General Public License version 3, or later</license> <creationDate>Nov 2012</creationDate> <version>4.3.1</version> <description>This plugin allows expiring subscription from certain plans when subscription for current plan active and subscribe for certain plans when subscription for current plan expired </description> <files> <filename plugin="subscriptioncontrol">subscriptioncontrol.php</filename> <folder>tmpl</folder> </files> <languages folder="language"> <language tag="en-GB">en-GB/en-GB.plg_osmembership_subscriptioncontrol.ini</language> </languages> <config> <fields name="params"> <fieldset name="basic"> <field name="show_on_frontend" type="radio" label="Show On Frontend" description="If set to Yes, this plugin will be available on frontend add/edit plan form" class="btn-group btn-group-yesno" default="0" > <option value="1">JYES</option> <option value="0">JNO</option> </field> </fieldset> </fields> </config> </extension> PK ! x�# # ! subscriptioncontrol/tmpl/form.phpnu �[��� <?php /** * @package Joomla * @subpackage Membership Pro * @author Tuan Pham Ngoc * @copyright Copyright (C) 2012 - 2025 Ossolution Team * @license GNU/GPL, see LICENSE.php */ defined('_JEXEC') or die; use Joomla\CMS\HTML\HTMLHelper; use Joomla\CMS\Language\Text; use Joomla\Registry\Registry; /** * Layout variables * ----------------- * @var array $options * @var OSMembershipTablePlan $row */ $params = new Registry($row->params); $expiringPlanIds = explode(',', $params->get('expiring_plan_ids', '')); $subscribePlanIds = explode(',', $params->get('subscription_expired_subscribe_plan_ids', '')); if ($this->app->isClient('site')) { $bootstrapHelper = OSMembershipHelperBootstrap::getInstance(); } else { $bootstrapHelper = OSMembershipHelperHtml::getAdminBootstrapHelper(); } ?> <div class="<?php echo $bootstrapHelper->getClassMapping('row-fluid'); ?>"> <div class="<?php echo $bootstrapHelper->getClassMapping('span6'); ?> pull-left"> <fieldset class="form-horizontal options-form"> <legend><?php echo Text::_('OSM_WHEN_SUBSCRIPTION_ACTIVE'); ?></legend> <div class="control-group"> <div class="control-label"> <?php echo Text::_('PLG_SUBSCRIPTION_CONTROL_EXPIRING_PLANS'); ?> </div> <div class="controls"> <?php echo OSMembershipHelperHtml::getChoicesJsSelect(HTMLHelper::_('select.genericlist', $options, 'expiring_plan_ids[]', ' multiple="multiple" size="6" class="form-select advSelect" ', 'value', 'text', $expiringPlanIds)); ?> </div> </div> </fieldset> </div> <div class="<?php echo $bootstrapHelper->getClassMapping('span6'); ?> pull-left"> <fieldset class="form-horizontal options-form"> <legend><?php echo Text::_('OSM_WHEN_SUBSCRIPTION_EXPIRED'); ?></legend> <div class="control-group"> <div class="control-label"> <?php echo Text::_('PLG_SUBSCRIPTION_CONTROL_SUBSCRIBE_PLANS'); ?> </div> <div class="controls"> <?php echo OSMembershipHelperHtml::getChoicesJsSelect(HTMLHelper::_('select.genericlist', $options, 'subscription_expired_subscribe_plan_ids[]', ' multiple="multiple" size="6" class="form-select advSelect" ', 'value', 'text', $subscribePlanIds)); ?> </div> </div> </fieldset> </div> </div> PK ! Y�X�� � http/http.phpnu �[��� <?php /** * @package Joomla * @subpackage Membership Pro * @author Tuan Pham Ngoc * @copyright Copyright (C) 2012 - 2025 Ossolution Team * @license GNU/GPL, see LICENSE.php */ use Joomla\CMS\Http\HttpFactory; use Joomla\CMS\Plugin\CMSPlugin; use Joomla\Database\DatabaseDriver; use Joomla\Event\Event; use Joomla\Event\SubscriberInterface; defined('_JEXEC') or die; class plgOSMembershipHttp extends CMSPlugin implements SubscriberInterface { /** * Database object. * * @var DatabaseDriver */ protected $db; public static function getSubscribedEvents(): array { return [ 'onAfterStoreSubscription' => 'onAfterStoreSubscription', 'onMembershipActive' => 'onMembershipActive', 'onMembershipExpire' => 'onMembershipExpire', ]; } /** * Subscription Store * * @param Event $event * * @return void */ public function onAfterStoreSubscription(Event $event): void { if (!in_array(0, (array) $this->params->get('send_webhook_on', [1]))) { return; } /* @var OSMembershipTableSubscriber $row */ [$row] = array_values($event->getArguments()); if (!str_contains($row->payment_method, 'os_offline')) { return; } $this->sendRequest($row, 'onAfterStoreSubscription'); } /** * Subscription Active * * @param Event $event * * @return void */ public function onMembershipActive(Event $event): void { if (!in_array(1, (array) $this->params->get('send_webhook_on', [1]))) { return; } /* @var OSMembershipTableSubscriber $row */ [$row] = array_values($event->getArguments()); $this->sendRequest($row, 'onMembershipActive'); } /** * Subscription Expired * * @param Event $event * * @return void */ public function onMembershipExpire(Event $event): void { if (!in_array(2, (array) $this->params->get('send_webhook_on', [1]))) { return; } /* @var OSMembershipTableSubscriber $row */ [$row] = array_values($event->getArguments()); $this->sendRequest($row, 'onMembershipExpire'); } /** * Send HTTP request * * @param OSMembershipTableSubscriber $row * @param string $event * * @return void */ private function sendRequest($row, $event): void { $url = $this->params->get('url'); if (!$url) { return; } JLoader::register('OSMembershipModelApi', JPATH_ROOT . '/components/com_osmembership/model/api.php'); $config = OSMembershipHelper::getConfig(); $db = $this->db; $query = $db->getQuery(true); /* @var OSMembershipModelApi $model */ $model = MPFModel::getTempInstance('Api', 'OSMembershipModel'); // Get custom fields data $data = $model->getSubscriptionData($row->id); // Add other subscription related data $subscriptionRelatedFields = [ 'id', 'plan_id', 'user_id', 'profile_id', 'from_date', 'to_date', 'created_date', 'subscription_id', 'amount', 'discount_amount', 'tax_amount', 'gross_amount', 'payment_processing_fee', 'transaction_id', 'tax_rate', 'payment_method', 'coupon_id', 'vies_registered', 'coupon_id', 'published', 'email',// Should not be needed here, just a special case for a customer ]; foreach ($subscriptionRelatedFields as $field) { $data[$field] = $row->{$field}; } // Other calculated fields $data['country_code'] = OSMembershipHelper::getCountryCode($row->country); if ($row->username) { $data['username'] = $row->username; } elseif ($row->user_id) { $query->select('username') ->from('#__users') ->where('id = ' . (int) $row->user_id); $db->setQuery($query); $data['username'] = $db->loadResult(); } else { $data['username'] = ''; } if ($row->coupon_id) { $query->clear() ->select($db->quoteName('code')) ->from('#__osmembership_coupons') ->where('id = ' . $row->coupon_id); $db->setQuery($query); $data['coupon_code'] = $db->loadResult(); } else { $data['coupon_code'] = ''; } $data['membership_id'] = OSMembershipHelper::formatMembershipId($row, $config); $data['invoice_number'] = OSMembershipHelper::formatInvoiceNumber($row, $config); // Get plans related information $rowPlan = OSMembershipHelperDatabase::getPlan($row->plan_id); $data['plan_id'] = $rowPlan->id; $data['plan_title'] = $rowPlan->title; $data['plan_alias'] = $rowPlan->alias; $data['plan_price'] = $rowPlan->price; if ($rowPlan->category_id > 0) { $fieldSuffix = OSMembershipHelper::getFieldSuffix($row->language); $query->clear() ->select($db->quoteName('title' . $fieldSuffix)) ->from('#__osmembership_categories') ->where('id = ' . $rowPlan->category_id); $db->setQuery($query); $data['category'] = $db->loadResult(); } else { $data['category'] = ''; } if ($row->published == 0) { $data['subscription_status'] = 'Pending'; } elseif ($row->published == 1) { $data['subscription_status'] = 'Active'; } elseif ($row->published == 2) { $data['subscription_status'] = 'Expired'; } else { $data['subscription_status'] = 'Unknown'; } $data['event'] = $event; // OK, we will now make a post request with json data try { $http = HttpFactory::getHttp(); $data = $this->getMappedData($data); if ($this->params->get('content_type', 'application/json') === 'application/json') { $data = json_encode($data); } $http->post($url, $data, $this->getRequestHeaders()); } catch (Exception $e) { } } /** * Get request headers * * @return array */ private function getRequestHeaders(): array { $headers['Content-Type'] = $this->params->get('content_type', 'application/json'); foreach ($this->params->get('headers', []) as $header) { if (is_string($header->name) && is_string($header->value) && strlen(trim($header->name)) > 0 && strlen( trim($header->value) ) > 0) { $headers[$header->name] = $header->value; } } return $headers; } /** * Method to get request data in the mapped keys * * @param array $data * * @return array */ private function getMappedData(array $data): array { foreach ($this->params->get('fields_mapping', []) as $fieldMapping) { if (is_string($fieldMapping->original_field_name) && is_string($fieldMapping->new_field_name) && strlen(trim($fieldMapping->original_field_name)) > 0 && strlen(trim($fieldMapping->new_field_name)) > 0) { if (array_key_exists(trim($fieldMapping->original_field_name), $data)) { $data[trim($fieldMapping->new_field_name)] = $data[trim($fieldMapping->original_field_name)]; unset($data[trim($fieldMapping->original_field_name)]); } } } return $data; } }PK ! ��ߥ � http/http.xmlnu �[��� <?xml version="1.0" encoding="utf-8"?> <extension version="2.5.0" type="plugin" group="osmembership" method="upgrade"> <name>Membership Pro - Webhook</name> <author>Tuan Pham Ngoc</author> <authorEmail>tuanpn@joomdonation.com</authorEmail> <authorUrl>http://www.joomdonation.com</authorUrl> <copyright>Copyright (C) 2012 - 2025 Ossolution Team</copyright> <license>GNU General Public License version 3, or later</license> <creationDate>Jan 2024</creationDate> <version>4.3.1</version> <description>This plugin will make a HTTP POST REQUEST to configured URL when subscription becomes active.</description> <files> <filename plugin="http">http.php</filename> </files> <config> <fields name="params"> <fieldset name="basic"> <field name="url" type="url" default="" label="URL" description="The URL which will receive data from Membership Pro" /> <field name="content_type" type="list" label="Content Type" default="application/json"> <option value="application/json">application/json</option> <option value="application/x-www-form-urlencoded">application/x-www-form-urlencoded</option> </field> <field name="send_webhook_on" multiple="true" type="list" label="Send Webhook On" default="1"> <option value="0">Subscription Store Offline Payment</option> <option value="1">Subscription Active</option> <option value="2">Subscription Expired</option> </field> </fieldset> <fieldset name="headers" label="HTTP Headers" description="HTTP headers (beside Content-Type header which is sent by default) you want to send in the request"> <field name="headers" type="subform" layout="joomla.form.field.subform.repeatable-table" icon="list" multiple="true" > <form hidden="true" name="list_headers" repeat="true"> <field name="name" type="text" label="Name" /> <field name="value" type="text" label="Value" /> </form> </field> </fieldset> <fieldset name="fields_mapping" label="Fields Mapping" description="If the external system which you want to pass data to expects to receive difference field with the field passed by the plugin, define the field mapping here (kind of field name alias). For example, the plugin pass first_name by default, but your system expect to receive firstname, you can add a mapping first_name => firstname"> <field name="fields_mapping" type="subform" layout="joomla.form.field.subform.repeatable-table" icon="list" multiple="true" > <form hidden="true" name="fields_mapping" repeat="true"> <field name="original_field_name" type="text" label="Original Field Name" /> <field name="new_field_name" type="text" label="New Field Name" /> </form> </field> </fieldset> </fields> </config> </extension>PK ! ��7� joomlagroups/joomlagroups.xmlnu �[��� <?xml version="1.0" encoding="utf-8"?> <extension version="4.2.0" type="plugin" group="osmembership" method="upgrade"> <name>Membership Pro - Joomla Groups</name> <author>Tuan Pham Ngoc</author> <authorEmail>tuanpn@joomdonation.com</authorEmail> <authorUrl>https://joomdonation.com</authorUrl> <copyright>Copyright (C) 2012 - 2025 Ossolution Team</copyright> <license>GNU General Public License version 3, or later</license> <creationDate>Nov 2012</creationDate> <version>4.3.1</version> <description>This plugin is used to assign users to Joomla Groups when they subscribe to a Subscription Plan in Membership Pro </description> <files> <filename plugin="joomlagroups">joomlagroups.php</filename> <folder>tmpl</folder> </files> <languages folder="language"> <language tag="en-GB">en-GB/en-GB.plg_osmembership_joomlagroups.ini</language> </languages> <config> <fields name="params"> <fieldset name="basic"> <field name="exclude_user_groups" type="Usergrouplist" label="Exclude User Groups" multiple="true" layout="joomla.form.field.list-fancy-select" description="Select the user groups which you want to be excluded for selecting on frontend plans management" /> <field name="show_on_frontend" type="radio" label="Show On Frontend" description="If set to Yes, this plugin will be available on frontend add/edit plan form" class="btn-group btn-group-yesno" default="0" > <option value="1">JYES</option> <option value="0">JNO</option> </field> </fieldset> </fields> </config> </extension> PK ! ,�a�# �# joomlagroups/joomlagroups.phpnu �[��� <?php /** * @package Joomla * @subpackage Membership Pro * @author Tuan Pham Ngoc * @copyright Copyright (C) 2012 - 2025 Ossolution Team * @license GNU/GPL, see LICENSE.php */ defined('_JEXEC') or die; use Joomla\CMS\Application\CMSApplication; use Joomla\CMS\Component\ComponentHelper; use Joomla\CMS\Factory; use Joomla\CMS\Helper\UserGroupsHelper; use Joomla\CMS\HTML\HTMLHelper; use Joomla\CMS\Language\Text; use Joomla\CMS\Plugin\CMSPlugin; use Joomla\CMS\Plugin\PluginHelper; use Joomla\Database\DatabaseDriver; use Joomla\Event\Event; use Joomla\Event\SubscriberInterface; use Joomla\Registry\Registry; use Joomla\Utilities\ArrayHelper; class plgOSMembershipJoomlagroups extends CMSPlugin implements SubscriberInterface { use MPFEventResult; /** * Application object. * * @var CMSApplication */ protected $app; /** * Database object. * * @var DatabaseDriver */ protected $db; public static function getSubscribedEvents(): array { return [ 'onEditSubscriptionPlan' => 'onEditSubscriptionPlan', 'onAfterSaveSubscriptionPlan' => 'onAfterSaveSubscriptionPlan', 'onMembershipActive' => 'onMembershipActive', 'onMembershipExpire' => 'onMembershipExpire', ]; } /** * Render settings from * * @param Event $event * * @return void */ public function onEditSubscriptionPlan(Event $event): void { /* @var OSMembershipTablePlan $row */ [$row] = array_values($event->getArguments()); if (!$this->isExecutable()) { return; } ob_start(); $this->loadLanguage(); $this->drawSettingForm($row); $form = ob_get_contents(); ob_end_clean(); $result = [ 'title' => Text::_('PLG_OSMEMBERSHIP_JOOMLA_GROUPS_SETTINGS'), 'form' => $form, ]; $this->addResult($event, $result); } /** * Store setting into database * * @param Event $event * * @return void */ public function onAfterSaveSubscriptionPlan(Event $event): void { /** * @var string $context * @var OSMembershipTablePlan $row * @var array $data * @var $isNew */ [$context, $row, $data, $isNew] = array_values($event->getArguments()); if (!$this->isExecutable()) { return; } $params = new Registry($row->params); $keys = ['joomla_group_ids', 'remove_joomla_group_ids', 'subscription_expired_joomla_group_ids', 'joomla_expried_group_ids']; foreach ($keys as $key) { $params->set($key, implode(',', $data[$key] ?? [])); } $row->params = $params->toString(); $row->store(); } /** * Run when a membership activated * * @param Event $event * * @return void */ public function onMembershipActive(Event $event): void { /* @var OSMembershipTableSubscriber $row */ [$row] = array_values($event->getArguments()); if (!$row->user_id) { return; } $user = Factory::getUser($row->user_id); $currentGroups = $user->groups; $plan = new OSMembershipTablePlan($this->db); $plan->load($row->plan_id); $params = new Registry($plan->params); $groups = explode(',', $params->get('joomla_group_ids', '')); $removeGroupIds = explode(',', $params->get('remove_joomla_group_ids', '')); $currentGroups = array_unique(array_merge($currentGroups, $groups)); if ($row->group_admin_id > 0 && PluginHelper::isEnabled('osmembership', 'groupmembership')) { // This is group member, need to exclude from some groups if needed $plugin = PluginHelper::getPlugin('osmembership', 'groupmembership'); if ($plugin) { $params = new Registry($plugin->params); $excludeGroupIds = $params->get('exclude_group_ids', [7, 8]); if ($excludeGroupIds) { if (is_string($excludeGroupIds)) { $excludeGroupIds = explode(',', $excludeGroupIds); } $excludeGroupIds = ArrayHelper::toInteger($excludeGroupIds); $currentGroups = array_diff($currentGroups, $excludeGroupIds); } } } // Get Joomla group from custom fields selection $currentGroups = array_merge($currentGroups, $this->getJoomlaGroupsFromFields($row)); // Remove from Joomla groups when active $currentGroups = array_diff($currentGroups, $removeGroupIds); $user->groups = $currentGroups; $user->save(true); } /** * Run when a membership expiried die * * @param Event $event * * @return void */ public function onMembershipExpire(Event $event): void { /* @var OSMembershipTableSubscriber $row */ [$row] = array_values($event->getArguments()); if (!$row->user_id) { return; } $user = Factory::getUser($row->user_id); $currentGroups = $user->groups; $plan = new OSMembershipTablePlan($this->db); $plan->load($row->plan_id); $params = new Registry($plan->params); $groups = explode(',', $params->get('joomla_expried_group_ids', '')); $subscriptionExpiredGroupIds = explode(',', $params->get('subscription_expired_joomla_group_ids', '')); $activePlans = OSMembershipHelperSubscription::getActiveMembershipPlans($row->user_id, [$row->id]); // Subscriber should be removed from the user groups which he is assigned to from custom fields if he does not have active subscription of this plan anymore if (!in_array($row->plan_id, $activePlans)) { $customFieldUserGroups = $this->getJoomlaGroupsFromFields($row); if (count($customFieldUserGroups)) { $groups = array_merge($groups, $customFieldUserGroups); } } $db = $this->db; $query = $db->getQuery(true) ->select('params') ->from('#__osmembership_plans') ->where('id IN (' . implode(',', $activePlans) . ')'); $db->setQuery($query); $rowPlans = $db->loadObjectList(); // Subscribers will be assigned to this group if he has no more active subscription of this plan, haven't renewed yet if (!in_array($row->plan_id, $activePlans) && count($subscriptionExpiredGroupIds)) { // We need to remove he groups which is configured to be removed when there is active subscription of other plan foreach ($rowPlans as $rowPlan) { $planParams = new Registry($rowPlan->params); $planGroups = explode(',', $planParams->get('remove_joomla_group_ids', '')); $subscriptionExpiredGroupIds = array_diff($subscriptionExpiredGroupIds, $planGroups); } $currentGroups = array_merge($currentGroups, $subscriptionExpiredGroupIds); reset($rowPlans); } foreach ($rowPlans as $rowPlan) { $planParams = new Registry($rowPlan->params); $planGroups = explode(',', $planParams->get('joomla_group_ids', '')); $groups = array_diff($groups, $planGroups); } $currentGroups = array_filter(array_unique(array_diff($currentGroups, $groups))); // In case there is no user group left, assign it to default user group if (count($currentGroups) == 0) { $userComponentParams = ComponentHelper::getParams('com_users'); $currentGroups[] = $userComponentParams->get('new_usertype', 2); } $user->groups = $currentGroups; $user->save(true); } /** * Get Joomla groups from custom fields which subscriber select for their subscription * * @param OSMembershipTableSubscriber $row * * @return array */ private function getJoomlaGroupsFromFields($row) { $groups = []; $rowFields = OSMembershipHelper::getProfileFields($row->plan_id, true, $row->language, $row->act); $subscriptionData = OSMembershipHelper::getProfileData($row, $row->plan_id, $rowFields); foreach ($rowFields as $field) { if (empty($field->joomla_group_ids) || empty($field->values) || empty($subscriptionData[$field->name])) { continue; } $fieldValue = $subscriptionData[$field->name]; $groups = array_merge($groups, OSMembershipHelperSubscription::getUserGroupsFromFieldValue($field, $fieldValue)); } return $groups; } /** * Method to check if the plugin is executable * * @return bool */ private function isExecutable() { if ($this->app->isClient('site') && !$this->params->get('show_on_frontend')) { return false; } return true; } /** * Display form allows users to change setting for this subscription plan * * @param OSMembershipTablePlan $row */ private function drawSettingForm($row) { $excludeUserGroups = (array) $this->params->get('exclude_user_groups'); $groups = array_values(UserGroupsHelper::getInstance()->getAll()); $options = []; foreach ($groups as $group) { if ($this->app->isClient('site') && in_array($group->id, $excludeUserGroups)) { continue; } $options[] = HTMLHelper::_('select.option', $group->id, str_repeat('- ', $group->level) . $group->title); } require PluginHelper::getLayoutPath($this->_type, $this->_name, 'form'); } } PK ! O�Wm m joomlagroups/tmpl/form.phpnu �[��� <?php /** * @package Joomla * @subpackage Membership Pro * @author Tuan Pham Ngoc * @copyright Copyright (C) 2012 - 2025 Ossolution Team * @license GNU/GPL, see LICENSE.php */ defined('_JEXEC') or die; use Joomla\CMS\HTML\HTMLHelper; use Joomla\CMS\Language\Text; use Joomla\Registry\Registry; /** * Layout variables * ----------------- * @var array $options * @var OSMembershipTablePlan $row */ $params = new Registry($row->params); $activeGroupIds = explode(',', $params->get('joomla_group_ids', '')); $activeRemoveGroupIds = explode(',', $params->get('remove_joomla_group_ids', '')); $expiredRemoveGroupIds = explode(',', $params->get('joomla_expried_group_ids', '')); $expiredGroupIds = explode(',', $params->get('subscription_expired_joomla_group_ids', '')); if ($this->app->isClient('site')) { $bootstrapHelper = OSMembershipHelperBootstrap::getInstance(); } else { $bootstrapHelper = OSMembershipHelperHtml::getAdminBootstrapHelper(); } ?> <div class="<?php echo $bootstrapHelper->getClassMapping('row-fluid'); ?>"> <div class="<?php echo $bootstrapHelper->getClassMapping('span6'); ?> pull-left"> <fieldset class="form-horizontal options-form"> <legend><?php echo Text::_('OSM_WHEN_SUBSCRIPTION_ACTIVE'); ?></legend> <div class="control-group"> <div class="control-label"> <?php echo Text::_('PLG_OSMEMBERSHIP_JOOMLA_ASSIGN_TO_JOOMLA_GROUPS'); ?> </div> <div class="controls"> <?php echo OSMembershipHelperHtml::getChoicesJsSelect(HTMLHelper::_('select.genericlist', $options, 'joomla_group_ids[]', ' multiple="multiple" size="6" class="form-select advSelect" ', 'value', 'text', $activeGroupIds)); ?> </div> </div> <div class="control-group"> <div class="control-label"> <?php echo Text::_('PLG_OSMEMBERSHIP_JOOMLA_REMOVE_FROM_JOOMLA_GROUPS'); ?> </div> <div class="controls"> <?php echo OSMembershipHelperHtml::getChoicesJsSelect(HTMLHelper::_('select.genericlist', $options, 'remove_joomla_group_ids[]', ' multiple="multiple" size="6" class="form-select advSelect" ', 'value', 'text', $activeRemoveGroupIds)); ?> </div> </div> </fieldset> </div> <div class="<?php echo $bootstrapHelper->getClassMapping('span6'); ?> pull-left"> <fieldset class="form-horizontal options-form"> <legend><?php echo Text::_('OSM_WHEN_SUBSCRIPTION_EXPIRED'); ?></legend> <div class="control-group"> <div class="control-label"> <?php echo Text::_('PLG_OSMEMBERSHIP_JOOMLA_REMOVE_FROM_JOOMLA_GROUPS'); ?> </div> <div class="controls"> <?php echo OSMembershipHelperHtml::getChoicesJsSelect(HTMLHelper::_('select.genericlist', $options, 'joomla_expried_group_ids[]', ' multiple="multiple" size="6" class="form-select advSelect" ', 'value', 'text', $expiredRemoveGroupIds)); ?> </div> </div> <div class="control-group"> <div class="control-label"> <?php echo Text::_('PLG_OSMEMBERSHIP_JOOMLA_ASSIGN_TO_JOOMLA_GROUPS'); ?> </div> <div class="controls"> <?php echo OSMembershipHelperHtml::getChoicesJsSelect(HTMLHelper::_('select.genericlist', $options, 'subscription_expired_joomla_group_ids[]', ' multiple="multiple" size="6" class="form-select advSelect" ', 'value', 'text', $expiredGroupIds)); ?> </div> </div> </fieldset> </div> </div> PK ! iCB^j j autosubscribe/autosubscribe.xmlnu �[��� <?xml version="1.0" encoding="utf-8"?> <extension version="4.2.0" type="plugin" group="osmembership" method="upgrade"> <name>Membership Pro - Auto Subscribe</name> <author>Tuan Pham Ngoc</author> <authorEmail>tuanpn@joomdonation.com</authorEmail> <authorUrl>https://joomdonation.com</authorUrl> <copyright>Copyright (C) 2012 - 2025 Ossolution Team</copyright> <license>GNU General Public License version 3, or later</license> <creationDate>Nov 2012</creationDate> <version>4.3.1</version> <description>This plugin is used to subscribe users to pre-selected subscription plans when they subscribe to the main subscription plan. </description> <files> <filename plugin="autosubscribe">autosubscribe.php</filename> <folder>tmpl</folder> </files> <languages folder="language"> <language tag="en-GB">en-GB/en-GB.plg_osmembership_autosubscribe.ini</language> </languages> <config> <fields name="params"> <fieldset name="basic"> <field name="show_on_frontend" type="radio" label="Show On Frontend" description="If set to Yes, this plugin will be available on frontend add/edit plan form" class="btn-group btn-group-yesno" default="0" > <option value="1">JYES</option> <option value="0">JNO</option> </field> </fieldset> </fields> </config> </extension> PK ! ��D=� � autosubscribe/autosubscribe.phpnu �[��� <?php /** * @package Joomla * @subpackage Membership Pro * @author Tuan Pham Ngoc * @copyright Copyright (C) 2012 - 2025 Ossolution Team * @license GNU/GPL, see LICENSE.php */ defined('_JEXEC') or die; use Joomla\CMS\HTML\HTMLHelper; use Joomla\CMS\Language\Text; use Joomla\CMS\Plugin\CMSPlugin; use Joomla\CMS\Plugin\PluginHelper; use Joomla\Event\Event; use Joomla\Event\SubscriberInterface; use Joomla\Registry\Registry; class plgOSMembershipAutoSubscribe extends CMSPlugin implements SubscriberInterface { use MPFEventResult; /** * Application object. * * @var \Joomla\CMS\Application\CMSApplication */ protected $app; /** * Database object. * * @var \Joomla\Database\DatabaseDriver */ protected $db; public static function getSubscribedEvents(): array { return [ 'onEditSubscriptionPlan' => 'onEditSubscriptionPlan', 'onAfterSaveSubscriptionPlan' => 'onAfterSaveSubscriptionPlan', 'onMembershipActive' => 'onMembershipActive', ]; } /** * Render setting form * * @param Event $event * * @return void */ public function onEditSubscriptionPlan(Event $event): void { /* @var OSMembershipTablePlan $row */ [$row] = array_values($event->getArguments()); if (!$this->isExecutable()) { return; } ob_start(); $this->loadLanguage(); $this->drawSettingForm($row); $form = ob_get_contents(); ob_end_clean(); $result = [ 'title' => Text::_('PLG_AUTO_SUBSCRIBE'), 'form' => $form, ]; $this->addResult($event, $result); } /** * Store setting into database, in this case, use params field of plans table * * @param Event $event * * @return void */ public function onAfterSaveSubscriptionPlan(Event $event): void { /** * @var string $context * @var OSMembershipTablePlan $row * @var array $data * @var $isNew */ [$context, $row, $data, $isNew] = array_values($event->getArguments()); if (!$this->isExecutable()) { return; } $params = new Registry($row->params); $params->set('auto_subscribe_plan_ids', implode(',', $data['auto_subscribe_plan_ids'] ?? [])); $row->params = $params->toString(); $row->store(); } /** * Run when a membership activated * * @param Event $event * * @return void */ public function onMembershipActive(Event $event): void { /* @var OSMembershipTableSubscriber $row */ [$row] = array_values($event->getArguments()); if ($row->auto_subscribe_processed) { return; } static $subscribedPlanIds = []; $rowPlan = new OSMembershipTablePlan($this->db); $rowPlan->load($row->plan_id); $params = new Registry($rowPlan->params); $planIds = explode(',', $params->get('auto_subscribe_plan_ids', '')); $planIds = array_filter($planIds); // Do not allow auto registering to the current plan $planIds = array_diff($planIds, [$row->plan_id]); if (empty($planIds)) { return; } /* @var OSMembershipModelApi $model */ $model = MPFModel::getInstance('Api', 'OSMembershipModel', ['ignore_request' => true, 'remember_states' => false]); // First, get details information about the subscription $data = $model->getSubscriptionData($row->id); $data['published'] = 1; $data['user_id'] = $row->user_id; $data['parent_id'] = $row->id; // Reset amount data, set it to 0 for the auto-subscribed subscription $data['amount'] = $data['discount_amount'] = $data['tax_amount'] = $data['payment_processing_fee'] = $data['tax_rate'] = 0; foreach ($planIds as $planId) { // Already registered, prevent registering again so that infinitive loop does not happen if (in_array($planId, $subscribedPlanIds)) { continue; } $subscribedPlanIds[] = $planId; $data['plan_id'] = $planId; try { $model->store($data); } catch (Exception $e) { } } } /** * Method to check if the plugin is executable * * @return bool */ private function isExecutable() { if ($this->app->isClient('site') && !$this->params->get('show_on_frontend')) { return false; } return true; } /** * Display form allows users to change settings on subscription plan add/edit screen * * @param OSMembershipTablePlan $row */ private function drawSettingForm($row) { $db = $this->db; $query = $db->getQuery(true) ->select('id, title') ->from('#__osmembership_plans') ->where('published = 1') ->order('title'); if ($row->id > 0) { $query->where('id != ' . $row->id); } $db->setQuery($query); $options = []; foreach ($db->loadObjectList() as $plan) { $options[] = HTMLHelper::_('select.option', $plan->id, $plan->title); } require PluginHelper::getLayoutPath($this->_type, $this->_name, 'form'); } } PK ! ���o� � autosubscribe/tmpl/form.phpnu �[��� <?php /** * @package Joomla * @subpackage Membership Pro * @author Tuan Pham Ngoc * @copyright Copyright (C) 2012 - 2025 Ossolution Team * @license GNU/GPL, see LICENSE.php */ defined('_JEXEC') or die; use Joomla\CMS\HTML\HTMLHelper; use Joomla\CMS\Language\Text; use Joomla\Registry\Registry; /** * Layout variables * ----------------- * @var array $options * @var array $planIds * @var OSMembershipTablePlan $row */ $params = new Registry($row->params); $planIds = explode(',', $params->get('auto_subscribe_plan_ids', '')); $planIds = array_filter($planIds); ?> <div class="control-group"> <div class="control-label"> <?php echo OSMembershipHelperHtml::getFieldLabel('auto_subscribe_plan_ids', Text::_('OSM_SELECT_PLANS'), Text::_('OSM_AUTO_SUBSCRIBE_PLAN_IDS_EXPLAIN')); ?> </div> <div class="controls"> <?php echo OSMembershipHelperHtml::getChoicesJsSelect(HTMLHelper::_('select.genericlist', $options, 'auto_subscribe_plan_ids[]', 'class="advSelect form-select" multiple="multiple" size="10"', 'value', 'text', $planIds)); ?> </div> </div> PK ! ����I I + registrationhistory/registrationhistory.xmlnu �[��� <?xml version="1.0" encoding="utf-8"?> <extension version="4.2.0" type="plugin" group="osmembership" method="upgrade"> <name>Membership Pro - Events Booking Registration History</name> <author>Tuan Pham Ngoc</author> <authorEmail>tuanpn@joomdonation.com</authorEmail> <authorUrl>https://joomdonation.com</authorUrl> <copyright>Copyright (C) 2012 - 2025 Ossolution Team</copyright> <license>GNU General Public License version 3, or later</license> <creationDate>Feb 2019</creationDate> <version>4.3.1</version> <description>This plugin display Registration History of the current user in his Membership Pro user profile </description> <files> <filename plugin="registrationhistory">registrationhistory.php</filename> <folder>tmpl</folder> </files> </extension> PK ! \l� + registrationhistory/registrationhistory.phpnu �[��� <?php /** * @package Joomla * @subpackage Membership Pro * @author Tuan Pham Ngoc * @copyright Copyright (C) 2012 - 2025 Ossolution Team * @license GNU/GPL, see LICENSE.php */ defined('_JEXEC') or die; use Joomla\CMS\Application\CMSApplication; use Joomla\CMS\Component\ComponentHelper; use Joomla\CMS\Language\Text; use Joomla\CMS\Plugin\CMSPlugin; use Joomla\CMS\Plugin\PluginHelper; use Joomla\CMS\Uri\Uri; use Joomla\Database\DatabaseDriver; use Joomla\Event\Event; use Joomla\Event\SubscriberInterface; class plgOSMembershipRegistrationhistory extends CMSPlugin implements SubscriberInterface { use MPFEventResult; /** * Application object. * * @var CMSApplication */ protected $app; /** * Database object. * * @var DatabaseDriver */ protected $db; public static function getSubscribedEvents(): array { return [ 'onProfileDisplay' => 'onProfileDisplay', ]; } /** * Render setting form * * @param Event $event * * @return void */ public function onProfileDisplay(Event $event): void { /* @var OSMembershipTableSubscriber $row */ [$row] = array_values($event->getArguments()); if ($this->app->isClient('administrator')) { return; } ob_start(); $this->drawRegistrationHistory($row); $result = [ 'title' => Text::_('EB_REGISTRATION_HISTORY'), 'form' => ob_get_clean(), ]; $this->addResult($event, $result); } /** * Register listeners * * @return void */ public function registerListeners() { if (!ComponentHelper::isEnabled('com_eventbooking')) { return; } parent::registerListeners(); } /** * Display registration history of the current logged in user * * @param OSMembershipTableSubscriber $row */ private function drawRegistrationHistory($row) { // Require libraries require_once JPATH_ADMINISTRATOR . '/components/com_eventbooking/libraries/rad/bootstrap.php'; EventbookingHelper::loadLanguage(); JLoader::register('EventbookingModelHistory', JPATH_ROOT . '/components/com_eventbooking/model/history.php'); /* @var EventbookingModelHistory $model */ $model = RADModel::getInstance('History', 'EventbookingModel', [ 'table_prefix' => '#__eb_', 'remember_states' => false, 'ignore_request' => true, ]); $model->setUserId($row->user_id); $items = $model->setState('limitstart', 0) ->setState('limit', 0) ->getData(); if (empty($items)) { return; } $config = EventbookingHelper::getConfig(); $showDownloadCertificate = false; $showDownloadTicket = false; $showDueAmountColumn = false; $numberPaymentMethods = EventbookingHelper::getNumberNoneOfflinePaymentMethods(); if ($numberPaymentMethods > 0) { foreach ($items as $item) { if ($item->payment_status != 1) { $showDueAmountColumn = true; break; } } } foreach ($items as $item) { $item->show_download_certificate = false; if ($item->published == 1 && $item->activate_certificate_feature == 1 && $item->event_end_date_minutes >= 0 && (!$config->download_certificate_if_checked_in || $item->checked_in) ) { $showDownloadCertificate = true; $item->show_download_certificate = true; } if ($item->ticket_code && $item->payment_status == 1) { $showDownloadTicket = true; } } $db = $this->db; $query = $db->getQuery(true) ->select('id') ->from('#__eb_payment_plugins') ->where('published = 1') ->where('name NOT LIKE "os_offline%"'); $db->setQuery($query); $onlinePaymentPlugins = $db->loadColumn(); if (in_array('last_name', EventbookingHelper::getPublishedCoreFields())) { $showLastName = true; } else { $showLastName = false; } $return = base64_encode(Uri::getInstance()->toString()); require PluginHelper::getLayoutPath('osmembership', 'registrationhistory', 'default'); } } PK ! �4�M�- �- $ registrationhistory/tmpl/default.phpnu �[��� <?php /** * @package Joomla * @subpackage Membership Pro * @author Tuan Pham Ngoc * @copyright Copyright (C) 2012 - 2025 Ossolution Team * @license GNU/GPL, see LICENSE.php */ defined('_JEXEC') or die; use Joomla\CMS\HTML\HTMLHelper; use Joomla\CMS\Language\Text; use Joomla\CMS\Router\Route; /** * Layout variables * * @var RADConfig $config * @var bool $showLastName * @var bool $showDownloadCertificate * @var bool $showDownloadTicket * @var bool $showDueAmountColumn * @var array $onlinePaymentPlugins */ $bootstrapHelper = OSMembershipHelperBootstrap::getInstance(); $hiddenPhoneClass = $bootstrapHelper->getClassMapping('hidden-phone'); $centerClass = $bootstrapHelper->getClassMapping('center'); $btnDanger = $bootstrapHelper->getClassMapping('btn btn-danger'); ?> <table class="<?php echo $bootstrapHelper->getClassMapping('table table-striped table-bordered'); ?> osm-responsive-table" id="adminForm"> <thead> <tr> <?php if ($config->get('history_show_first_name', 1)) { ?> <th> <?php echo Text::_('EB_FIRST_NAME'); ?> </th> <?php } if ($config->get('history_show_last_name', 1) && $showLastName) { ?> <th> <?php echo Text::_('EB_LAST_NAME'); ?> </th> <?php } ?> <th class="list_event"> <?php echo Text::_('EB_EVENT'); ?> </th> <?php if ($config->show_event_date) { ?> <th class="list_event_date"> <?php echo Text::_('EB_EVENT_DATE'); ?> </th> <?php } ?> <th class="list_event_date"> <?php echo Text::_('EB_REGISTRATION_DATE'); ?> </th> <?php if ($config->get('history_show_number_registrants', 1)) { ?> <th class="list_registrant_number <?php echo $hiddenPhoneClass; ?>"> <?php echo Text::_('EB_REGISTRANTS'); ?> </th> <?php } if ($config->get('history_show_amount', 1)) { ?> <th class="list_amount <?php echo $hiddenPhoneClass; ?>"> <?php echo Text::_('EB_AMOUNT'); ?> </th> <?php } if ($config->activate_deposit_feature && $showDueAmountColumn) { ?> <th style="text-align: right;"> <?php echo Text::_('EB_DUE_AMOUNT'); ?> </th> <?php } ?> <th class="list_id"> <?php echo Text::_('EB_REGISTRATION_STATUS'); ?> </th> <?php if ($config->activate_invoice_feature) { ?> <th class="<?php echo $centerClass; ?>"> <?php echo Text::_('EB_INVOICE_NUMBER'); ?> </th> <?php } if ($showDownloadTicket) { ?> <th class="<?php echo $centerClass; ?>"> <?php echo Text::_('EB_TICKET'); ?> </th> <?php } if ($showDownloadCertificate) { ?> <th class="<?php echo $centerClass; ?>"> <?php echo Text::_('EB_CERTIFICATE'); ?> </th> <?php } ?> </tr> </thead> <tbody> <?php $Itemid = EventbookingHelper::getItemid(); $registrantItemId = EventbookingHelperRoute::findView('history', $Itemid); for ($i = 0, $n = count($items); $i < $n; $i++) { $row = $items[$i]; $link = Route::_('index.php?option=com_eventbooking&view=registrant&id=' . $row->id . '&Itemid=' . $registrantItemId . '&return=' . $return); $eventLink = Route::_(EventbookingHelperRoute::getEventRoute($row->event_id, $row->main_category_id, $Itemid)); ?> <tr> <?php if ($config->get('history_show_first_name', 1)) { ?> <td class="tdno<?php echo $i; ?>" data-content="<?php echo Text::_('EB_FIRST_NAME'); ?>"> <a href="<?php echo $link; ?>"><?php echo $row->first_name; ?></a> </td> <?php } if ($config->get('history_show_last_name', 1) && $showLastName) { ?> <td class="tdno<?php echo $i; ?>" data-content="<?php echo Text::_('EB_LAST_NAME'); ?>"> <?php echo $row->last_name; ?> </td> <?php } ?> <td class="tdno<?php echo $i; ?>" data-content="<?php echo Text::_('EB_EVENT'); ?>"> <a href="<?php echo $eventLink; ?>" target="_blank"><?php echo $row->title; ?></a> </td> <?php if ($config->show_event_date) { ?> <td class="tdno<?php echo $i . ' ' . $centerClass; ?>" data-content="<?php echo Text::_('EB_EVENT_DATE'); ?>"> <?php if ($row->event_date == EB_TBC_DATE) { echo Text::_('EB_TBC'); } else { echo HTMLHelper::_('date', $row->event_date, $config->event_date_format, null); } ?> </td> <?php } ?> <td class="tdno<?php echo $i . ' ' . $centerClass; ?>" data-content="<?php echo Text::_('EB_REGISTRATION_DATE'); ?>"> <?php echo HTMLHelper::_('date', $row->register_date, $config->date_format); ?> </td> <?php if ($config->get('history_show_number_registrants', 1)) { ?> <td class="<?php echo $centerClass . ' ' . $hiddenPhoneClass; ?>" style="font-weight: bold;"> <?php echo $row->number_registrants; ?> </td> <?php } if ($config->get('history_show_amount', 1)) { ?> <td align="right" class="<?php echo $hiddenPhoneClass; ?>"> <?php echo EventbookingHelper::formatCurrency($row->amount, $config, $row->currency_symbol); ?> </td> <?php } if ($config->activate_deposit_feature && $showDueAmountColumn) { ?> <td style="text-align: right;" class="tdno<?php echo $i; ?>" data-content="<?php echo Text::_('EB_DUE_AMOUNT'); ?>"> <?php if ($row->payment_status != 1 && $row->published != 2) { // Check to see if there is an online payment method available for this event if ($row->payment_methods) { $hasOnlinePaymentMethods = count(array_intersect($onlinePaymentPlugins, explode(',', $row->payment_methods))); } else { $hasOnlinePaymentMethods = count($onlinePaymentPlugins); } echo EventbookingHelper::formatCurrency($row->amount - $row->deposit_amount, $config); if ($hasOnlinePaymentMethods && $row->group_id == 0) { ?> <a class="btn-primary" href="<?php echo Route::_('index.php?option=com_eventbooking&view=payment®istration_code=' . $row->registration_code . '&Itemid=' . $registrantItemId); ?>"><?php echo Text::_('EB_MAKE_PAYMENT'); ?></a> <?php } } ?> </td> <?php } ?> <td class="tdno<?php echo $i . ' ' . $centerClass; ?>" data-content="<?php echo Text::_('EB_REGISTRATION_STATUS'); ?>"> <?php switch ($row->published) { case 0 : echo Text::_('EB_PENDING'); break; case 1 : echo Text::_('EB_PAID'); break; case 2 : echo Text::_('EB_CANCELLED'); break; case 3: echo Text::_('EB_WAITING_LIST'); // If there is space, we will display payment link here to allow users to make payment to become registrants if ($config->enable_waiting_list_payment && $row->group_id == 0) { $event = EventbookingHelperDatabase::getEvent($row->event_id); if ($event->event_capacity == 0 || ($event->event_capacity - $event->total_registrants >= $row->number_registrants)) { // Check to see if there is an online payment method available for this event if ($row->payment_methods) { $hasOnlinePaymentMethods = count(array_intersect($onlinePaymentPlugins, explode(',', $row->payment_methods))); } else { $hasOnlinePaymentMethods = count($onlinePaymentPlugins); } if ($hasOnlinePaymentMethods) { ?> <a class="btn-primary" href="<?php echo Route::_('index.php?option=com_eventbooking&view=payment&layout=registration&order_number=' . $row->registration_code . '&Itemid=' . $registrantItemId); ?>"><?php echo Text::_('EB_MAKE_PAYMENT'); ?></a> <?php } } } break; } if (!$row->group_id && !empty($row->enable_cancel_registration) && in_array($row->published, [0, 1, 3]) && EventbookingHelperRegistration::canCancelRegistrationNow($row)) { if ($row->published == 3) { $buttonText = 'EB_CANCEL_WAITING_LIST'; } else { $buttonText = 'EB_CANCEL_REGISTRATION'; } ?> <a class="<?php echo $btnDanger; ?>" href="<?php echo Route::_('index.php?option=com_eventbooking&task=cancel_registration_confirm&cancel_code=' . $row->registration_code . '&Itemid=' . $this->Itemid); ?>"><?php echo Text::_($buttonText); ?></a> <?php } ?> </td> <?php if ($config->activate_invoice_feature) { ?> <td class="tdno<?php echo $i . ' ' . $centerClass; ?>" data-content="<?php echo Text::_('EB_INVOICE_NUMBER'); ?>"> <?php if ($row->invoice_number) { ?> <a href="<?php echo Route::_('index.php?option=com_eventbooking&task=registrant.download_invoice&id=' . ($row->cart_id ?: ($row->group_id ?: $row->id)) . '&Itemid=' . $registrantItemId); ?>" title="<?php echo Text::_('EB_DOWNLOAD'); ?>"><?php echo EventbookingHelper::formatInvoiceNumber($row->invoice_number, $config, $row); ?></a> <?php } ?> </td> <?php } if ($showDownloadTicket) { ?> <td class="tdno<?php echo $i . ' ' . $centerClass; ?>" data-content="<?php echo Text::_('EB_TICKET'); ?>"> <?php if ($row->ticket_code && $row->published == 1 && $row->payment_status == 1) { ?> <a href="<?php echo Route::_('index.php?option=com_eventbooking&task=registrant.download_ticket&id=' . $row->id . '&Itemid=' . $registrantItemId); ?>" title="<?php echo Text::_('EB_DOWNLOAD'); ?>"><?php echo $row->ticket_number ? EventbookingHelperTicket::formatTicketNumber($row->ticket_prefix, $row->ticket_number, $config) : Text::_('EB_DOWNLOAD_TICKETS'); ?></a> <?php } ?> </td> <?php } if ($showDownloadCertificate) { ?> <td class="tdno<?php echo $i . ' ' . $centerClass; ?>" data-content="<?php echo Text::_('EB_CERTIFICATE'); ?>"> <?php if ($row->show_download_certificate) { ?> <a href="<?php echo Route::_('index.php?option=com_eventbooking&task=registrant.download_certificate&id=' . $row->id); ?>" title="<?php echo Text::_('EB_DOWNLOAD'); ?>"><?php echo EventbookingHelper::formatCertificateNumber($row->id, $config); ?></a> <?php } ?> </td> <?php } ?> </tr> <?php } ?> </tbody> </table> PK ! ��F mailchimp/mailchimp.xmlnu �[��� <?xml version="1.0" encoding="utf-8"?> <extension version="4.2.0" type="plugin" group="osmembership" method="upgrade"> <name>Membership Pro - Mailchimp</name> <author>Tuan Pham Ngoc</author> <authorEmail>tuanpn@joomdonation.com</authorEmail> <authorUrl>https://joomdonation.com</authorUrl> <copyright>Copyright (C) 2012 - 2025 Ossolution Team</copyright> <license>GNU General Public License version 3, or later</license> <creationDate>Nov 2012</creationDate> <version>4.3.1</version> <description>This plugin is used to add subscribers to Mailchimp when they sign up for a subscription plan in Membership Pro extension </description> <files> <filename plugin="mailchimp">mailchimp.php</filename> <folder>api</folder> <folder>tmpl</folder> </files> <languages folder="language"> <language tag="en-GB">en-GB/en-GB.plg_osmembership_mailchimp.ini</language> </languages> <config> <fields name="params"> <fieldset name="basic"> <field name="api_key" type="text" size="60" default="" label="API Key" description="Your Mailchimp API Key"/> <field name="double_optin" type="list" label="Double opt-in" default="0"> <option value="0">No</option> <option value="1">Yes</option> </field> <field name="subscribe_group_members" type="radio" label="Subscribe Group Members" description="If set to No, group members won't be subscribed to MailChimp" class="btn-group btn-group-yesno" default="1" > <option value="1">JYES</option> <option value="0">JNO</option> </field> <field name="show_on_frontend" type="radio" label="Show On Frontend" description="If set to Yes, this plugin will be available on frontend add/edit plan form" class="btn-group btn-group-yesno" default="0" > <option value="1">JYES</option> <option value="0">JNO</option> </field> </fieldset> </fields> </config> </extension> PK ! �3@ 3@ mailchimp/api/MailChimp.phpnu �[��� <?php namespace DrewM\MailChimp; /** * Super-simple, minimum abstraction MailChimp API v3 wrapper * MailChimp API v3: http://developer.mailchimp.com * This wrapper: https://github.com/drewm/mailchimp-api * * @author Drew McLellan <drew.mclellan@gmail.com> * @version 2.5 */ class MailChimp { private $api_key; private $api_endpoint = 'https://<dc>.api.mailchimp.com/3.0'; public const TIMEOUT = 10; /* SSL Verification Read before disabling: http://snippets.webaware.com.au/howto/stop-turning-off-curlopt_ssl_verifypeer-and-fix-your-php-config/ */ public $verify_ssl = true; private $request_successful = false; private $last_error = ''; private $last_response = array(); private $last_request = array(); /** * Create a new instance * * @param string $api_key Your MailChimp API key * @param string $api_endpoint Optional custom API endpoint * * @throws \Exception */ public function __construct($api_key, $api_endpoint = null) { if (!\function_exists('curl_init') || !\function_exists('curl_setopt')) { throw new \Exception("cURL support is required, but can't be found."); } $this->api_key = $api_key; if ($api_endpoint === null) { if (!str_contains($this->api_key, '-')) { throw new \Exception("Invalid MailChimp API key `{$api_key}` supplied."); } list(, $data_center) = explode('-', $this->api_key); $this->api_endpoint = str_replace('<dc>', $data_center, $this->api_endpoint); } else { $this->api_endpoint = $api_endpoint; } $this->last_response = array('headers' => null, 'body' => null); } /** * Create a new instance of a Batch request. Optionally with the ID of an existing batch. * * @param string $batch_id Optional ID of an existing batch, if you need to check its status for example. * * @return Batch New Batch object. */ public function new_batch($batch_id = null) { return new Batch($this, $batch_id); } /** * @return string The url to the API endpoint */ public function getApiEndpoint() { return $this->api_endpoint; } /** * Convert an email address into a 'subscriber hash' for identifying the subscriber in a method URL * * @param string $email The subscriber's email address * * @return string Hashed version of the input */ public function subscriberHash($email) { return md5(strtolower($email)); } /** * Was the last request successful? * * @return bool True for success, false for failure */ public function success() { return $this->request_successful; } /** * Get the last error returned by either the network transport, or by the API. * If something didn't work, this should contain the string describing the problem. * * @return string|false describing the error */ public function getLastError() { return $this->last_error ?: false; } /** * Get an array containing the HTTP headers and the body of the API response. * * @return array Assoc array with keys 'headers' and 'body' */ public function getLastResponse() { return $this->last_response; } /** * Get an array containing the HTTP headers and the body of the API request. * * @return array Assoc array */ public function getLastRequest() { return $this->last_request; } /** * Make an HTTP DELETE request - for deleting data * * @param string $method URL of the API request method * @param array $args Assoc array of arguments (if any) * @param int $timeout Timeout limit for request in seconds * * @return array|false Assoc array of API response, decoded from JSON */ public function delete($method, $args = array(), $timeout = self::TIMEOUT) { return $this->makeRequest('delete', $method, $args, $timeout); } /** * Make an HTTP GET request - for retrieving data * * @param string $method URL of the API request method * @param array $args Assoc array of arguments (usually your data) * @param int $timeout Timeout limit for request in seconds * * @return array|false Assoc array of API response, decoded from JSON */ public function get($method, $args = array(), $timeout = self::TIMEOUT) { return $this->makeRequest('get', $method, $args, $timeout); } /** * Make an HTTP PATCH request - for performing partial updates * * @param string $method URL of the API request method * @param array $args Assoc array of arguments (usually your data) * @param int $timeout Timeout limit for request in seconds * * @return array|false Assoc array of API response, decoded from JSON */ public function patch($method, $args = array(), $timeout = self::TIMEOUT) { return $this->makeRequest('patch', $method, $args, $timeout); } /** * Make an HTTP POST request - for creating and updating items * * @param string $method URL of the API request method * @param array $args Assoc array of arguments (usually your data) * @param int $timeout Timeout limit for request in seconds * * @return array|false Assoc array of API response, decoded from JSON */ public function post($method, $args = array(), $timeout = self::TIMEOUT) { return $this->makeRequest('post', $method, $args, $timeout); } /** * Make an HTTP PUT request - for creating new items * * @param string $method URL of the API request method * @param array $args Assoc array of arguments (usually your data) * @param int $timeout Timeout limit for request in seconds * * @return array|false Assoc array of API response, decoded from JSON */ public function put($method, $args = array(), $timeout = self::TIMEOUT) { return $this->makeRequest('put', $method, $args, $timeout); } /** * Performs the underlying HTTP request. Not very exciting. * * @param string $http_verb The HTTP verb to use: get, post, put, patch, delete * @param string $method The API method to be called * @param array $args Assoc array of parameters to be passed * @param int $timeout * * @return array|false Assoc array of decoded result */ private function makeRequest($http_verb, $method, $args = array(), $timeout = self::TIMEOUT) { $url = $this->api_endpoint . '/' . $method; $response = $this->prepareStateForRequest($http_verb, $method, $url, $timeout); $httpHeader = array( 'Accept: application/vnd.api+json', 'Content-Type: application/vnd.api+json', 'Authorization: apikey ' . $this->api_key, ); if (isset($args['language'])) { $httpHeader[] = 'Accept-Language: ' . $args['language']; } $ch = curl_init(); curl_setopt($ch, CURLOPT_URL, $url); curl_setopt($ch, CURLOPT_HTTPHEADER, $httpHeader); curl_setopt($ch, CURLOPT_USERAGENT, 'DrewM/MailChimp-API/3.0 (github.com/drewm/mailchimp-api)'); curl_setopt($ch, CURLOPT_RETURNTRANSFER, true); curl_setopt($ch, CURLOPT_VERBOSE, true); curl_setopt($ch, CURLOPT_HEADER, true); curl_setopt($ch, CURLOPT_TIMEOUT, $timeout); curl_setopt($ch, CURLOPT_SSL_VERIFYPEER, $this->verify_ssl); curl_setopt($ch, CURLOPT_HTTP_VERSION, CURL_HTTP_VERSION_1_0); curl_setopt($ch, CURLOPT_ENCODING, ''); curl_setopt($ch, CURLINFO_HEADER_OUT, true); switch ($http_verb) { case 'post': curl_setopt($ch, CURLOPT_POST, true); $this->attachRequestPayload($ch, $args); break; case 'get': $query = http_build_query($args, '', '&'); curl_setopt($ch, CURLOPT_URL, $url . '?' . $query); break; case 'delete': curl_setopt($ch, CURLOPT_CUSTOMREQUEST, 'DELETE'); break; case 'patch': curl_setopt($ch, CURLOPT_CUSTOMREQUEST, 'PATCH'); $this->attachRequestPayload($ch, $args); break; case 'put': curl_setopt($ch, CURLOPT_CUSTOMREQUEST, 'PUT'); $this->attachRequestPayload($ch, $args); break; } $responseContent = curl_exec($ch); $response['headers'] = curl_getinfo($ch); $response = $this->setResponseState($response, $responseContent, $ch); $formattedResponse = $this->formatResponse($response); curl_close($ch); $isSuccess = $this->determineSuccess($response, $formattedResponse, $timeout); return \is_array($formattedResponse) ? $formattedResponse : $isSuccess; } /** * @param string $http_verb * @param string $method * @param string $url * @param integer $timeout * * @return array */ private function prepareStateForRequest($http_verb, $method, $url, $timeout) { $this->last_error = ''; $this->request_successful = false; $this->last_response = array( 'headers' => null, // array of details from curl_getinfo() 'httpHeaders' => null, // array of HTTP headers 'body' => null, // content of the response ); $this->last_request = array( 'method' => $http_verb, 'path' => $method, 'url' => $url, 'body' => '', 'timeout' => $timeout, ); return $this->last_response; } /** * Get the HTTP headers as an array of header-name => header-value pairs. * * The "Link" header is parsed into an associative array based on the * rel names it contains. The original value is available under * the "_raw" key. * * @param string $headersAsString * * @return array */ private function getHeadersAsArray($headersAsString) { $headers = array(); foreach (explode("\r\n", $headersAsString) as $i => $line) { if ($i === 0) { // HTTP code continue; } $line = trim($line); if (empty($line)) { continue; } list($key, $value) = explode(': ', $line); if ($key == 'Link') { $value = array_merge( array('_raw' => $value), $this->getLinkHeaderAsArray($value) ); } $headers[$key] = $value; } return $headers; } /** * Extract all rel => URL pairs from the provided Link header value * * Mailchimp only implements the URI reference and relation type from * RFC 5988, so the value of the header is something like this: * * 'https://us13.api.mailchimp.com/schema/3.0/Lists/Instance.json; rel="describedBy", * <https://us13.admin.mailchimp.com/lists/members/?id=XXXX>; rel="dashboard"' * * @param string $linkHeaderAsString * * @return array */ private function getLinkHeaderAsArray($linkHeaderAsString) { $urls = array(); if (preg_match_all('/<(.*?)>\s*;\s*rel="(.*?)"\s*/', $linkHeaderAsString, $matches)) { foreach ($matches[2] as $i => $relName) { $urls[$relName] = $matches[1][$i]; } } return $urls; } /** * Encode the data and attach it to the request * * @param resource $ch cURL session handle, used by reference * @param array $data Assoc array of data to attach */ private function attachRequestPayload(&$ch, $data) { $encoded = json_encode($data); $this->last_request['body'] = $encoded; curl_setopt($ch, CURLOPT_POSTFIELDS, $encoded); } /** * Decode the response and format any error messages for debugging * * @param array $response The response from the curl request * * @return array|false The JSON decoded into an array */ private function formatResponse($response) { $this->last_response = $response; if (!empty($response['body'])) { return json_decode($response['body'], true); } return false; } /** * Do post-request formatting and setting state from the response * * @param array $response The response from the curl request * @param string $responseContent The body of the response from the curl request * @param resource $ch The curl resource * * @return array The modified response */ private function setResponseState($response, $responseContent, $ch) { if ($responseContent === false) { $this->last_error = curl_error($ch); } else { $headerSize = $response['headers']['header_size']; $response['httpHeaders'] = $this->getHeadersAsArray(substr($responseContent, 0, $headerSize)); $response['body'] = substr($responseContent, $headerSize); if (isset($response['headers']['request_header'])) { $this->last_request['headers'] = $response['headers']['request_header']; } } return $response; } /** * Check if the response was successful or a failure. If it failed, store the error. * * @param array $response The response from the curl request * @param array|false $formattedResponse The response body payload from the curl request * @param int $timeout The timeout supplied to the curl request. * * @return bool If the request was successful */ private function determineSuccess($response, $formattedResponse, $timeout) { $status = $this->findHTTPStatus($response, $formattedResponse); if ($status >= 200 && $status <= 299) { $this->request_successful = true; return true; } if (isset($formattedResponse['detail'])) { $this->last_error = sprintf('%d: %s', $formattedResponse['status'], $formattedResponse['detail']); return false; } if ($timeout > 0 && $response['headers'] && $response['headers']['total_time'] >= $timeout) { $this->last_error = sprintf('Request timed out after %f seconds.', $response['headers']['total_time']); return false; } $this->last_error = 'Unknown error, call getLastResponse() to find out what happened.'; return false; } /** * Find the HTTP status code from the headers or API response body * * @param array $response The response from the curl request * @param array|false $formattedResponse The response body payload from the curl request * * @return int HTTP status code */ private function findHTTPStatus($response, $formattedResponse) { if (!empty($response['headers']) && isset($response['headers']['http_code'])) { return (int) $response['headers']['http_code']; } if (!empty($response['body']) && isset($formattedResponse['status'])) { return (int) $formattedResponse['status']; } return 418; } } PK ! *�e6�* �* mailchimp/mailchimp.phpnu �[��� <?php /** * @package Joomla * @subpackage Membership Pro * @author Tuan Pham Ngoc * @copyright Copyright (C) 2012 - 2025 Ossolution Team * @license GNU/GPL, see LICENSE.php */ defined('_JEXEC') or die; use DrewM\MailChimp\MailChimp; use Joomla\CMS\Application\CMSApplication; use Joomla\CMS\HTML\HTMLHelper; use Joomla\CMS\Language\Text; use Joomla\CMS\Mail\MailHelper; use Joomla\CMS\Plugin\CMSPlugin; use Joomla\CMS\Plugin\PluginHelper; use Joomla\Database\DatabaseDriver; use Joomla\Event\Event; use Joomla\Event\SubscriberInterface; use Joomla\Registry\Registry; class plgOSMembershipMailchimp extends CMSPlugin implements SubscriberInterface { use MPFEventResult; /** * Application object. * * @var CMSApplication */ protected $app; /** * Database object. * * @var DatabaseDriver */ protected $db; public static function getSubscribedEvents(): array { return [ 'onEditSubscriptionPlan' => 'onEditSubscriptionPlan', 'onAfterSaveSubscriptionPlan' => 'onAfterSaveSubscriptionPlan', 'onMembershipActive' => 'onMembershipActive', 'onMembershipExpire' => 'onMembershipExpire', ]; } /** * Render setting form * * @param Event $event * * @return void */ public function onEditSubscriptionPlan(Event $event): void { /* @var OSMembershipTablePlan $row */ [$row] = array_values($event->getArguments()); if (!$this->isExecutable()) { return; } if (!class_exists('DrewM\\MailChimp\\MailChimp')) { require_once dirname(__FILE__) . '/api/MailChimp.php'; } ob_start(); $this->loadLanguage(); $this->drawSettingForm($row); $form = ob_get_contents(); ob_end_clean(); $result = [ 'title' => Text::_('PLG_OSMEMBERSHIP_MAILCHIMP_SETTINGS'), 'form' => $form, ]; $this->addResult($event, $result); } /** * Store setting into database, in this case, use params field of plans table * * @param Event $event * * @return void */ public function onAfterSaveSubscriptionPlan(Event $event): void { /** * @var string $context * @var OSMembershipTablePlan $row * @var array $data * @var $isNew */ [$context, $row, $data, $isNew] = array_values($event->getArguments()); if (!$this->isExecutable()) { return; } $params = new Registry($row->params); foreach (['mailchimp_list_ids', 'remove_mailchimp_list_ids', 'mailchimp_group_ids', 'remove_mailchimp_group_ids'] as $key) { $params->set($key, implode(',', $data[$key] ?? [])); } $row->params = $params->toString(); $row->store(); } /** * Run when a membership activated * * @param Event $event * * @return void */ public function onMembershipActive(Event $event): void { /* @var OSMembershipTableSubscriber $row */ [$row] = array_values($event->getArguments()); if (!class_exists('DrewM\\MailChimp\\MailChimp')) { require_once dirname(__FILE__) . '/api/MailChimp.php'; } if (!MailHelper::isEmailAddress($row->email)) { return; } if ($row->group_admin_id > 0 && $this->params->get('subscribe_group_members', '1') == '0') { return; } $config = OSMembershipHelper::getConfig(); // In case subscriber doesn't want to subscribe to newsleter, stop if ($config->show_subscribe_newsletter_checkbox && empty($row->subscribe_newsletter)) { return; } $plan = new OSMembershipTablePlan($this->db); $plan->load($row->plan_id); $params = new Registry($plan->params); $listIds = array_filter(explode(',', $params->get('mailchimp_list_ids', ''))); $groupIds = array_filter(explode(',', $params->get('mailchimp_group_ids', ''))); $listGroupMap = []; foreach ($groupIds as $groupId) { [$groupListId, $id] = explode('-', $groupId); $listGroupMap[$groupListId][] = $id; } if (empty($listIds)) { return; } try { $mailchimp = new MailChimp($this->params->get('api_key', '')); } catch (Exception $e) { return; } if ($this->params->get('double_optin')) { $status = 'pending'; } else { $status = 'subscribed'; } foreach ($listIds as $listId) { $data = [ 'skip_merge_validation' => true, 'id' => $listId, 'email_address' => $row->email, 'merge_fields' => [], 'status' => $status, 'update_existing' => true, ]; if ($row->first_name) { $data['merge_fields']['FNAME'] = $row->first_name; } if ($row->last_name) { $data['merge_fields']['LNAME'] = $row->last_name; } if ($row->address && $row->address2 && $row->city && $row->state && $row->zip) { $data['merge_fields']['ADDRESS'] = [ 'addr1' => $row->address, 'addr2' => $row->address2, 'city' => $row->city, 'state' => $row->state, 'zip' => $row->zip, 'country' => $row->country ?: $config->get('default_country'), ]; } if ($row->phone) { $data['merge_fields']['PHONE'] = $row->phone; } if (!empty($listGroupMap[$listId])) { $data['interests'] = []; foreach ($listGroupMap[$listId] as $interestId) { $data['interests'][$interestId] = true; } } $result = $mailchimp->post("lists/$listId/members", $data); if ($result === false) { $this->logError($data, $mailchimp->getLastError()); } } } /** * Run when a membership expired * * @param Event $event * * @return void */ public function onMembershipExpire(Event $event): void { /* @var OSMembershipTableSubscriber $row */ [$row] = array_values($event->getArguments()); if (!class_exists('DrewM\\MailChimp\\MailChimp')) { require_once dirname(__FILE__) . '/api/MailChimp.php'; } if (!MailHelper::isEmailAddress($row->email)) { return; } if ($row->group_admin_id > 0 && $this->params->get('subscribe_group_members', '1') == '0') { return; } $plan = new OSMembershipTablePlan($this->db); $plan->load($row->plan_id); $params = new Registry($plan->params); $listIds = array_filter(explode(',', $params->get('remove_mailchimp_list_ids', ''))); $groupIds = array_filter(explode(',', $params->get('remove_mailchimp_group_ids', ''))); if (empty($listIds) && empty($groupIds)) { return; } $activePlans = OSMembershipHelperSubscription::getActiveMembershipPlans($row->user_id, [$row->id]); // Subscription was already renewed, no need to process further if (in_array($row->plan_id, $activePlans)) { return; } $db = $this->db; $query = $db->getQuery(true) ->select('params') ->from('#__osmembership_plans') ->where('id IN (' . implode(',', $activePlans) . ')'); $db->setQuery($query); $rowPlans = $db->loadObjectList(); foreach ($rowPlans as $rowPlan) { $planParams = new Registry($rowPlan->params); $planListIds = array_filter(explode(',', $planParams->get('mailchimp_list_ids'))); $planGroupIds = array_filter(explode(',', $planParams->get('mailchimp_group_ids'))); $listIds = array_diff($listIds, $planListIds); $groupIds = array_diff($groupIds, $planGroupIds); } if (empty($listIds) && empty($groupIds)) { return; } try { $mailchimp = new MailChimp($this->params->get('api_key', '')); } catch (Exception $e) { return; } $hash = $mailchimp->subscriberHash($row->email); foreach ($listIds as $listId) { $result = $mailchimp->delete("lists/$listId/members/$hash"); if ($result === false) { $this->logError(['listId' => $listId, 'email' => $row->email], $mailchimp->getLastError()); } } if (count($groupIds)) { $listGroupMap = []; foreach ($groupIds as $groupId) { [$groupListId, $id] = explode('-', $groupId); $listGroupMap[$groupListId][] = $id; } foreach ($listGroupMap as $listId => $groups) { $data = ['email_address' => $row->email]; foreach ($groups as $group) { $data['interests'][$group] = false; } $result = $mailchimp->patch("lists/$listId/members/$hash?skip_merge_validation=true", $data); if ($result === false) { $this->logError($data, $mailchimp->getLastError()); } } } } /** * Display form allows users to change settings on subscription plan add/edit screen * * @param object $row */ private function drawSettingForm($row) { try { $mailchimp = new MailChimp($this->params->get('api_key', '')); } catch (Exception $e) { return; } $lists = $mailchimp->get('lists', ['count' => 1000]); if ($lists === false) { $this->app->enqueueMessage('No Mailing Lists Found', 'warning'); return; } $options = []; $allListIds = []; foreach ($lists['lists'] as $list) { $options[] = HTMLHelper::_('select.option', $list['id'], $list['name']); $allListIds[] = $list['id']; } $groupOptions = []; foreach ($allListIds as $listId) { $interestCategoriesResponse = $mailchimp->get('lists/' . $listId . '/interest-categories', ['count' => 1000]); foreach ($interestCategoriesResponse['categories'] as $category) { $interestsResponse = $mailchimp->get( 'lists/' . $listId . '/interest-categories/' . $category['id'] . '/interests', ['count' => 1000] ); foreach ($interestsResponse['interests'] as $interest) { $groupOptions[] = HTMLHelper::_('select.option', $listId . '-' . $interest['id'], $category['title'] . '-' . $interest['name']); } } } require PluginHelper::getLayoutPath($this->_type, $this->_name, 'form'); } /** * Method to check if the plugin is executable * * @return bool */ private function isExecutable() { if ($this->app->isClient('site') && !$this->params->get('show_on_frontend')) { return false; } return true; } /** * Log the error from API call * * @param array $data * @param string $error */ protected function logError($data, $error) { $text = '[' . date('m/d/Y g:i A') . '] - '; foreach ($data as $key => $value) { if (is_array($value)) { foreach ($value as $keyValue => $valueValue) { $text .= "$keyValue=$valueValue, "; } } else { $text .= "$key=$value, "; } } $text .= $error; $ipnLogFile = JPATH_ROOT . '/components/com_osmemership/mailchimp_api_errors.txt'; $fp = fopen($ipnLogFile, 'a'); fwrite($fp, $text . "\n\n"); fclose($fp); } } PK ! ˸w(v v mailchimp/tmpl/form.phpnu �[��� <?php /** * @package Joomla * @subpackage Membership Pro * @author Tuan Pham Ngoc * @copyright Copyright (C) 2012 - 2025 Ossolution Team * @license GNU/GPL, see LICENSE.php */ defined('_JEXEC') or die; use Joomla\CMS\HTML\HTMLHelper; use Joomla\CMS\Language\Text; use Joomla\Registry\Registry; /** * Layout variables * ----------------- * @var array $options * @var array $allListIds * @var array $groupOptions * @var OSMembershipTablePlan $row */ $params = new Registry($row->params); $listIds = explode(',', $params->get('mailchimp_list_ids', '')); $removeListIds = explode(',', $params->get('remove_mailchimp_list_ids', '')); if ($this->app->isClient('site')) { $bootstrapHelper = OSMembershipHelperBootstrap::getInstance(); } else { $bootstrapHelper = OSMembershipHelperHtml::getAdminBootstrapHelper(); } ?> <div class="<?php echo $bootstrapHelper->getClassMapping('row-fluid'); ?>"> <div class="<?php echo $bootstrapHelper->getClassMapping('span6 pull-left'); ?>"> <fieldset class="form-horizontal options-form"> <legend><?php echo Text::_('OSM_WHEN_SUBSCRIPTION_ACTIVE'); ?></legend> <div class="control-group"> <div class="control-label"> <?php echo OSMembershipHelperHtml::getFieldLabel('mailchimp_list_ids', Text::_('PLG_MAILCHIMP_ASSIGN_TO_LISTS'), Text::_('PLG_MAILCHIMP_ASSIGN_TO_LISTS_EXPLAIN')); ?> </div> <div class="controls"> <?php echo OSMembershipHelperHtml::getChoicesJsSelect(HTMLHelper::_('select.genericlist', $options, 'mailchimp_list_ids[]', 'class="form-select advSelect" multiple="multiple" size="10"', 'value', 'text', $listIds)); ?> </div> </div> <?php if (count($groupOptions)) { ?> <div class="control-group"> <div class="control-label"> <?php echo OSMembershipHelperHtml::getFieldLabel('mailchimp_group_ids', Text::_('PLG_MAILCHIMP_ADD_TO_GROUPS'), Text::_('PLG_MAILCHIMP_ADD_TO_GROUPS_EXPLAIN')); ?> </div> <div class="controls"> <?php echo OSMembershipHelperHtml::getChoicesJsSelect(HTMLHelper::_('select.genericlist', $groupOptions, 'mailchimp_group_ids[]', 'class="form-select advSelect" multiple="multiple" size="10"', 'value', 'text', explode(',', $params->get('mailchimp_group_ids')))); ?> </div> </div> <?php } ?> </fieldset> </div> <div class="<?php echo $bootstrapHelper->getClassMapping('span6 pull-left'); ?>"> <fieldset class="form-horizontal options-form"> <legend><?php echo Text::_('OSM_WHEN_SUBSCRIPTION_EXPIRED'); ?></legend> <div class="control-group"> <div class="control-label"> <?php echo OSMembershipHelperHtml::getFieldLabel('remove_mailchimp_list_ids', Text::_('PLG_MAILCHIMP_REMOVE_FROM_MAILING_LISTS'), Text::_('PLG_MAILCHIMP_REMOVE_FROM_MAILING_LISTS_EXPLAIN')); ?> </div> <div class="controls"> <?php echo OSMembershipHelperHtml::getChoicesJsSelect(HTMLHelper::_('select.genericlist', $options, 'remove_mailchimp_list_ids[]', 'class="form-select advSelect" multiple="multiple" size="10"', 'value', 'text', $removeListIds)); ?> </div> </div> <?php if (count($groupOptions)) { ?> <div class="control-group"> <div class="control-label"> <?php echo OSMembershipHelperHtml::getFieldLabel('remove_mailchimp_group_ids', Text::_('PLG_MAILCHIMP_REMOVE_FROM_GROUPS'), Text::_('PLG_MAILCHIMP_REMOVE_FROM_GROUPS_EXPLAIN')); ?> </div> <div class="controls"> <?php echo OSMembershipHelperHtml::getChoicesJsSelect(HTMLHelper::_('select.genericlist', $groupOptions, 'remove_mailchimp_group_ids[]', 'class="form-select advSelect" multiple="multiple" size="10"', 'value', 'text', explode(',', $params->get('remove_mailchimp_group_ids')))); ?> </div> </div> <?php } ?> </fieldset> </div> </div> PK ! ����� � k2groups/k2groups.phpnu �[��� <?php /** * @package Joomla * @subpackage Membership Pro * @author Tuan Pham Ngoc * @copyright Copyright (C) 2012 - 2025 Ossolution Team * @license GNU/GPL, see LICENSE.php */ defined('_JEXEC') or die; use Joomla\CMS\Application\CMSApplication; use Joomla\CMS\Component\ComponentHelper; use Joomla\CMS\HTML\HTMLHelper; use Joomla\CMS\Language\Text; use Joomla\CMS\Plugin\CMSPlugin; use Joomla\CMS\Plugin\PluginHelper; use Joomla\Database\DatabaseDriver; use Joomla\Event\Event; use Joomla\Event\SubscriberInterface; use Joomla\Registry\Registry; class plgOSMembershipK2groups extends CMSPlugin implements SubscriberInterface { use MPFEventResult; /** * Application object. * * @var CMSApplication */ protected $app; /** * Database object. * * @var DatabaseDriver */ protected $db; public static function getSubscribedEvents(): array { return [ 'onEditSubscriptionPlan' => 'onEditSubscriptionPlan', 'onAfterSaveSubscriptionPlan' => 'onAfterSaveSubscriptionPlan', 'onMembershipActive' => 'onMembershipActive', 'onMembershipExpire' => 'onMembershipExpire', ]; } /** * Render settings from * * @param Event $event * * @return void */ public function onEditSubscriptionPlan(Event $event): void { /* @var OSMembershipTablePlan $row */ [$row] = array_values($event->getArguments()); if (!$this->isExecutable()) { return; } ob_start(); $this->loadLanguage(); $this->drawSettingForm($row); $form = ob_get_contents(); ob_end_clean(); $result = [ 'title' => Text::_('PLG_OSMEMBERSHIP_K2_GROUPS_SETTINGS'), 'form' => $form, ]; $this->addResult($event, $result); } /** * Store setting into database * * @param Event $event * * @return void */ public function onAfterSaveSubscriptionPlan(Event $event): void { /** * @var string $context * @var OSMembershipTablePlan $row * @var array $data * @var $isNew */ [$context, $row, $data, $isNew] = array_values($event->getArguments()); if (!$this->isExecutable()) { return; } $params = new Registry($row->params); $params->set('k2_group_id', $data['k2_group_id']); $params->set('k2_expired_group_id', $data['k2_expired_group_id']); $row->params = $params->toString(); $row->store(); } /** * Run when a membership activated * * @param Event $event * * @return void */ public function onMembershipActive(Event $event): void { /* @var OSMembershipTableSubscriber $row */ [$row] = array_values($event->getArguments()); if (!$row->user_id) { return; } $params = $this->getPlanParams($row->plan_id); if ($k2GroupId = (int) $params->get('k2_group_id', '0')) { $this->assignUserToK2Group($row->user_id, $k2GroupId); } } /** * Run when a membership expired * * @param Event $event * * @return void */ public function onMembershipExpire(Event $event): void { /* @var OSMembershipTableSubscriber $row */ [$row] = array_values($event->getArguments()); if (!$row->user_id) { return; } $activePlans = OSMembershipHelperSubscription::getActiveMembershipPlans($row->user_id, [$row->id]); // Users has renewed their subscription before, don't process further if (in_array($row->plan_id, $activePlans)) { return; } $params = $this->getPlanParams($row->plan_id); if ($k2ExpiredGroupId = (int) $params->get('k2_expired_group_id', '0')) { $this->assignUserToK2Group($row->user_id, $k2ExpiredGroupId); } } /** * Register listeners * * @return void */ public function registerListeners() { if (!ComponentHelper::isEnabled('com_k2')) { return; } parent::registerListeners(); } /** * Method to check if the plugin is executable * * @return bool */ private function isExecutable() { if ($this->app->isClient('site') && !$this->params->get('show_on_frontend')) { return false; } return true; } /** * Display form allows users to change setting for this subscription plan * * @param OSMembershipTablePlan $row */ private function drawSettingForm($row) { $db = $this->db; $query = $db->getQuery(true) ->select('id AS value, name AS text')->from('#__k2_user_groups'); $db->setQuery($query); $options = $db->loadObjectList(); array_unshift($options, HTMLHelper::_('select.option', '', Text::_('PLG_OSMEMBERSHIP_SELECT_K2_GROUP'))); require PluginHelper::getLayoutPath($this->_type, $this->_name, 'form'); } /** * Assign a user to selected K2 Group * * @param $userId * @param $k2GroupId */ private function assignUserToK2Group($userId, $k2GroupId) { $db = $this->db; $query = $db->getQuery(true); $query->select('id') ->from('#__k2_users') ->where('userID =' . $userId); $db->setQuery($query); $k2UserId = $db->loadResult(); if ($k2UserId) { $query->clear()->update('#__k2_users')->set('`group`=' . $k2GroupId)->where('id =' . $k2UserId); } else { $query->clear()->insert('#__k2_users')->set('`group`=' . $k2GroupId)->set('`userID`=' . $userId); } $db->setQuery($query) ->execute(); } /** * Method to get the plan params * * @param int $planId * * @return Registry */ private function getPlanParams($planId) { $db = $this->db; $query = $db->getQuery(true); $query->select('`params`') ->from('#__osmembership_plans') ->where('id = ' . (int) $planId); $db->setQuery($query); return new Registry($db->loadResult()); } } PK ! f��mG G k2groups/k2groups.xmlnu �[��� <?xml version="1.0" encoding="utf-8"?> <extension version="4.2.0" type="plugin" group="osmembership" method="upgrade"> <name>Membership Pro - K2 Groups</name> <author>Tuan Pham Ngoc</author> <creationDate>Apirl 2012</creationDate> <copyright>Copyright (C) 2012 - 2025 Ossolution Team</copyright> <license>http://www.gnu.org/licenses/gpl-2.0.html GNU/GPL</license> <authorEmail>tuanpn@joomdonation.com</authorEmail> <authorUrl>www.joomdonation.com</authorUrl> <version>4.3.1</version> <description>This plugin is used to assign users to K2 Groups when they subscribe to a Subscription Plan in Membership Pro </description> <files> <filename plugin="k2groups">k2groups.php</filename> <folder>tmpl</folder> </files> <languages folder="language"> <language tag="en-GB">en-GB/en-GB.plg_osmembership_k2groups.ini</language> </languages> <config> <fields name="params"> <fieldset name="basic"> <field name="show_on_frontend" type="radio" label="Show On Frontend" description="If set to Yes, this plugin will be available on frontend add/edit plan form" class="btn-group btn-group-yesno" default="0" > <option value="1">JYES</option> <option value="0">JNO</option> </field> </fieldset> </fields> </config> </extension> PK ! .�z�V V k2groups/tmpl/form.phpnu �[��� <?php /** * @package Joomla * @subpackage Membership Pro * @author Tuan Pham Ngoc * @copyright Copyright (C) 2012 - 2025 Ossolution Team * @license GNU/GPL, see LICENSE.php */ defined('_JEXEC') or die; use Joomla\CMS\HTML\HTMLHelper; use Joomla\CMS\Language\Text; use Joomla\Registry\Registry; /** * Layout variables * ----------------- * @var array $options * @var OSMembershipTablePlan $row */ $params = new Registry($row->params); $k2GroupId = $params->get('k2_group_id', ''); $k2ExpiredGroupId = $params->get('k2_expired_group_id', ''); ?> <div class="control-group"> <div class="control-label"> <?php echo OSMembershipHelperHtml::getFieldLabel('k2_group_id', Text::_('PLG_OSMEMBERSHIP_K2GROUP_ASSIGN_TO_GROUP'), Text::_('PLG_OSMEMBERSHIP_K2GROUP_ASSIGN_TO_GROUP_EXPLAIN')); ?> </div> <div class="controls"> <?php echo OSMembershipHelperHtml::getChoicesJsSelect(HTMLHelper::_('select.genericlist', $options, 'k2_group_id', '', 'value', 'text', $k2GroupId)); ?> </div> </div> <div class="control-group"> <div class="control-label"> <?php echo OSMembershipHelperHtml::getFieldLabel('k2_expired_group_id', Text::_('PLG_OSMEMBERSHIP_K2GROUP_SUBSCRIPTION_EXPIRED_ASSIGN_TO_GROUPS'), Text::_('PLG_OSMEMBERSHIP_K2GROUP_SUBSCRIPTION_EXPIRED_ASSIGN_TO_GROUPS_EXPLAIN')); ?> </div> <div class="controls"> <?php echo OSMembershipHelperHtml::getChoicesJsSelect(HTMLHelper::_('select.genericlist', $options, 'k2_expired_group_id', '', 'value', 'text', $k2ExpiredGroupId)); ?> </div> </div> PK ! Y�t.� � cb/cb.xmlnu �[��� <?xml version="1.0" encoding="utf-8"?> <extension version="4.2.0" type="plugin" group="osmembership" method="upgrade"> <name>Membership Pro - CB</name> <author>Tuan Pham Ngoc</author> <authorEmail>tuanpn@joomdonation.com</authorEmail> <authorUrl>https://joomdonation.com</authorUrl> <copyright>Copyright (C) 2012 - 2025 Ossolution Team</copyright> <license>GNU General Public License version 3, or later</license> <creationDate>Nov 2012</creationDate> <version>4.3.1</version> <description>This plugin is used to create a CB account for user when they subscribe to a Subscription Plan in Membership Pro </description> <files> <filename plugin="cb">cb.php</filename> </files> <config> <fields name="params"> <fieldset name="basic"> <field name="block_user_on_membership_expire" type="radio" default="0" label="Block User When Membership Expired" description="Block User when Membership Expired"> <option value="0">No</option> <option value="1">Yes</option> </field> <field name="synchronize_data_for_pending_subscription" type="radio" default="0" label="Synchronize Data For Pending Subscriptions" description="If set to Yes, when users use offline payment and their subscription status is Pending, the data is also synchronized"> <option value="0">No</option> <option value="1">Yes</option> </field> </fieldset> </fields> </config> </extension>PK ! ��Ƚ � cb/cb.phpnu �[��� <?php /** * @package Joomla * @subpackage Membership Pro * @author Tuan Pham Ngoc * @copyright Copyright (C) 2012 - 2025 Ossolution Team * @license GNU/GPL, see LICENSE.php */ defined('_JEXEC') or die; use Joomla\CMS\Component\ComponentHelper; use Joomla\CMS\Plugin\CMSPlugin; use Joomla\Event\Event; use Joomla\Event\SubscriberInterface; class plgOSMembershipCB extends CMSPlugin implements SubscriberInterface { use MPFEventResult; /** * Application object. * * @var \Joomla\CMS\Application\CMSApplication */ protected $app; /** * Database object. * * @var \Joomla\Database\DatabaseDriver */ protected $db; public static function getSubscribedEvents(): array { return [ 'onGetFields' => 'onGetFields', 'onGetProfileData' => 'onGetProfileData', 'onAfterStoreSubscription' => 'onAfterStoreSubscription', 'onMembershipActive' => 'onMembershipActive', 'onMembershipExpire' => 'onMembershipExpire', 'onProfileUpdate' => 'onProfileUpdate', ]; } /** * Method to get list of custom fields in Community builder used to map with fields in Membership Pro * * @param Event $event * * @return void */ public function onGetFields(Event $event): void { $db = $this->db; $sql = 'SELECT name AS `value`, name AS `text` FROM #__comprofiler_fields WHERE `table`="#__comprofiler"'; $db->setQuery($sql); $this->addResult($event, $db->loadObjectList()); } /** * Method to get data stored in CB profile of the given user * * @param Event $event * * @return void */ public function onGetProfileData(Event $event): void { [$userId, $mappings] = array_values($event->getArguments()); $synchronizer = new MPFSynchronizerCommunitybuilder(); $this->addResult($event, $synchronizer->getData($userId, $mappings)); } /** * Method to create a CB account for subscriber if it does not exist yet * * @param Event $event * * @return void */ public function onAfterStoreSubscription(Event $event): void { /* @var OSMembershipTableSubscriber $row */ [$row] = array_values($event->getArguments()); if (!$row->user_id) { return; } if ($this->params->get('synchronize_data_for_pending_subscription') && str_contains($row->payment_method, 'os_offline')) { $this->createOrUpdateCBAccount($row); } } /** * Method to create a CB account for subscriber if it does not exist yet * * @param Event $event * * @return void */ public function onMembershipActive(Event $event): void { /* @var OSMembershipTableSubscriber $row */ [$row] = array_values($event->getArguments()); if (!$row->user_id) { return; } $this->createOrUpdateCBAccount($row); // Update the block field in users table $config = OSMembershipHelper::getConfig(); if (!$config->send_activation_email) { $db = $this->db; $sql = 'UPDATE #__users SET `block` = 0 WHERE id = ' . $row->user_id; $db->setQuery($sql); $db->execute(); $this->setCBAuth($row->user_id, 1); } } /** * Method to block the CB account when the subscription record is expired * * @param Event $event * * @return void */ public function onMembershipExpire(Event $event): void { /* @var OSMembershipTableSubscriber $row */ [$row] = array_values($event->getArguments()); $blockUser = $this->params->get('block_user_on_membership_expire', 0); if ($row->user_id && $blockUser) { $activePlanIds = OSMembershipHelperSubscription::getActiveMembershipPlans($row->user_id); if (count($activePlanIds) == 2 && $activePlanIds[1] == $row->plan_id) { $this->setCBAuth($row->user_id, 0); } } } /** * Method to update CB profile when subscriber update his profile in Membership Pro * * @param Event $event * * @return void */ public function onProfileUpdate(Event $event): void { /* @var OSMembershipTableSubscriber $row */ [$row] = array_values($event->getArguments()); if (!$row->user_id) { return; } $this->createOrUpdateCBAccount($row); } /** * Method to create / update a CB account for subscriber * * @param OSMembershipTableSubscriber $row The subscription record */ private function createOrUpdateCBAccount($row) { $config = OSMembershipHelper::getConfig(); $db = $this->db; $sql = 'SELECT count(*) FROM `#__comprofiler` WHERE `user_id` = ' . $db->quote($row->user_id); $db->setQuery($sql); $count = $db->loadResult(); $sql = ' SHOW FIELDS FROM #__comprofiler '; $db->setQuery($sql); $fields = $db->loadObjectList(); $fieldList = []; for ($i = 0, $n = count($fields); $i < $n; $i++) { $field = $fields[$i]; $fieldList[] = $field->Field; } //Get list of fields belong to table $sql = 'SELECT name, field_mapping FROM #__osmembership_fields WHERE field_mapping != "" AND field_mapping IS NOT NULL AND is_core = 1'; $db->setQuery($sql); $fields = $db->loadObjectList(); $fieldValues = []; if (count($fields)) { foreach ($fields as $field) { $fieldName = $field->field_mapping; if ($fieldName && in_array($fieldName, $fieldList)) { $fieldValues[$fieldName] = $row->{$field->name}; } } } $sql = 'SELECT a.field_mapping, b.field_value FROM #__osmembership_fields AS a ' . ' INNER JOIN #__osmembership_field_value AS b ' . ' ON a.id = b.field_id ' . ' WHERE b.subscriber_id=' . $row->id; $db->setQuery($sql); $fields = $db->loadObjectList(); if (count($fields)) { foreach ($fields as $field) { if ($field->field_mapping && in_array($field->field_mapping, $fieldList)) { //Check if this is a json value if (is_string($field->field_value) && is_array(json_decode($field->field_value))) { $fieldValues[$field->field_mapping] = implode('|*|', json_decode($field->field_value)); } else { $fieldValues[$field->field_mapping] = $field->field_value; } } } } $profile = new stdClass(); $profile->id = $row->user_id; $profile->user_id = $row->user_id; $profile->firstname = $row->first_name; $profile->lastname = $row->last_name; if (!$config->use_cb_api) { $profile->avatarapproved = 1; $profile->confirmed = 1; $profile->registeripaddr = htmlspecialchars($_SERVER['REMOTE_ADDR']); $profile->banned = 0; $profile->acceptedterms = 1; } foreach ($fieldValues as $fieldName => $value) { $profile->{$fieldName} = $value; } if ($count) { $db->updateObject('#__comprofiler', $profile, 'id'); } else { $db->insertObject('#__comprofiler', $profile); } } /** * Register listeners * * @return void */ public function registerListeners() { if (!ComponentHelper::isEnabled('com_comprofiler')) { return; } $option = $this->app->getInput()->getCmd('option', ''); if ($option === 'com_comprofiler') { return; } // Require library + register autoloader require_once JPATH_ADMINISTRATOR . '/components/com_osmembership/loader.php'; parent::registerListeners(); } /** * Method to block / unblock a CB account * * @param int $userId * @param int $auth */ private function setCBAuth($userId, $auth) { $auth = $auth ? 1 : 0; $userId = (int) $userId; $sql = "UPDATE `#__comprofiler` SET `approved` = $auth, `confirmed` = $auth, `acceptedterms` = $auth WHERE `user_id` = $userId"; $db = $this->db; $db->setQuery($sql); $db->execute(); } } PK ! 8>�k� � script/tmpl/form.phpnu �[��� <?php /** * @package Joomla * @subpackage Membership Pro * @author Tuan Pham Ngoc * @copyright Copyright (C) 2012 - 2025 Ossolution Team * @license GNU/GPL, see LICENSE.php */ defined('_JEXEC') or die; use Joomla\CMS\Editor\Editor; use Joomla\CMS\Language\Text; use Joomla\CMS\Plugin\PluginHelper; use Joomla\Registry\Registry; /** * Layout variables * ----------------- * @var OSMembershipTablePlan $row */ $params = new Registry($row->params); if (PluginHelper::isEnabled('editors', 'codemirror')) { $editorPlugin = 'codemirror'; } elseif (PluginHelper::isEnabled('editor', 'none')) { $editorPlugin = 'none'; } else { $editorPlugin = null; } if ($editorPlugin) { $editor = Editor::getInstance($editorPlugin); } else { $editor = null; } ?> <p class="text-warning"> This feature is usually used by developers that know how to write PHP code. Please only use this feature if you know how to program in PHP and understand what you are doing. </p> <div class="control-group"> <div class="control-label"> <?php echo OSMembershipHelperHtml::getFieldLabel('subscription_store_script', Text::_('OSM_SUBSCRIPTION_STORED_SCRIPT'), Text::_('OSM_SUBSCRIPTION_STORED_SCRIPT_EXPLAIN')); ?> </div> <div class="controls"> <?php if ($editor) { echo $editor->display('subscription_store_script', $params->get('subscription_store_script'), '100%', '250', '75', '10', false, null, null, null, ['syntax' => 'php']); } else { ?> <textarea rows="10" cols="70" class="form-control" name="subscription_store_script"><?php echo $params->get('subscription_store_script'); ?></textarea> <?php } ?> </div> </div> <div class="control-group"> <div class="control-label"> <?php echo OSMembershipHelperHtml::getFieldLabel('subscription_active_script', Text::_('OSM_SUBSCRIPTION_ACTIVE_SCRIPT'), Text::_('OSM_SUBSCRIPTION_ACTIVE_SCRIPT_EXPLAIN')); ?> </div> <div class="controls"> <?php if ($editor) { echo $editor->display('subscription_active_script', $params->get('subscription_active_script'), '100%', '250', '75', '10', false, null, null, null, ['syntax' => 'php']); } else { ?> <textarea rows="10" cols="70" class="form-control" name="subscription_active_script"><?php echo $params->get('subscription_active_script'); ?></textarea> <?php } ?> </div> </div> <div class="control-group"> <div class="control-label"> <?php echo OSMembershipHelperHtml::getFieldLabel('subscription_expired_script', Text::_('OSM_SUBSCRIPTION_EXPIRED_SCRIPT'), Text::_('OSM_SUBSCRIPTION_EXPIRED_SCRIPT_EXPLAIN')); ?> </div> <div class="controls"> <?php if ($editor) { echo $editor->display('subscription_expired_script', $params->get('subscription_expired_script'), '100%', '250', '75', '10', false, null, null, null, ['syntax' => 'php']); } else { ?> <textarea rows="10" cols="70" class="form-control" name="subscription_expired_script"><?php echo $params->get('subscription_expired_script'); ?></textarea> <?php } ?> </div> </div> <div class="control-group"> <div class="control-label"> <?php echo OSMembershipHelperHtml::getFieldLabel('subscription_update_script', Text::_('OSM_SUBSCRIPTION_UPDATE_SCRIPT'), Text::_('OSM_SUBSCRIPTION_UPDATE_SCRIPT_EXPLAIN')); ?> </div> <div class="controls"> <?php if ($editor) { echo $editor->display('subscription_update_script', $params->get('subscription_update_script'), '100%', '250', '75', '10', false, null, null, null, ['syntax' => 'php']); } else { ?> <textarea rows="10" cols="70" class="form-control" name="subscription_update_script"><?php echo $params->get('subscription_update_script'); ?></textarea> <?php } ?> </div> </div>PK ! �<ͣM M script/script.xmlnu �[��� <?xml version="1.0" encoding="utf-8"?> <extension version="4.2.0" type="plugin" group="osmembership" method="upgrade"> <name>Membership Pro - PHP Script</name> <author>Tuan Pham Ngoc</author> <authorEmail>tuanpn@joomdonation.com</authorEmail> <authorUrl>https://joomdonation.com</authorUrl> <copyright>Copyright (C) 2012 - 2025 Ossolution Team</copyright> <license>GNU General Public License version 3, or later</license> <creationDate>Nov 2012</creationDate> <version>4.3.1</version> <description>This plugin allow running PHP script (including Joomla code) in Membership Pro when subscription stored, active or expired </description> <files> <filename plugin="script">script.php</filename> <folder>tmpl</folder> </files> <languages folder="language"> <language tag="en-GB">en-GB/en-GB.plg_osmembership_script.ini</language> </languages> <config> <fields name="params"> <fieldset name="basic"> <field name="show_on_frontend" type="radio" label="Show On Frontend" description="If set to Yes, this plugin will be available on frontend add/edit plan form" class="btn-group btn-group-yesno" default="0" > <option value="1">JYES</option> <option value="0">JNO</option> </field> </fieldset> </fields> </config> </extension>PK ! ���� script/script.phpnu �[��� <?php /** * @package Joomla * @subpackage Membership Pro * @author Tuan Pham Ngoc * @copyright Copyright (C) 2012 - 2025 Ossolution Team * @license GNU/GPL, see LICENSE.php */ defined('_JEXEC') or die; use Joomla\CMS\Application\CMSApplication; use Joomla\CMS\Language\Text; use Joomla\CMS\Plugin\CMSPlugin; use Joomla\CMS\Plugin\PluginHelper; use Joomla\Database\DatabaseDriver; use Joomla\Event\Event; use Joomla\Event\SubscriberInterface; use Joomla\Registry\Registry; class plgOSMembershipScript extends CMSPlugin implements SubscriberInterface { use MPFEventResult; /** * Application object. * * @var CMSApplication */ protected $app; /** * Database object. * * @var DatabaseDriver */ protected $db; public static function getSubscribedEvents(): array { return [ 'onEditSubscriptionPlan' => 'onEditSubscriptionPlan', 'onAfterSaveSubscriptionPlan' => 'onAfterSaveSubscriptionPlan', 'onAfterStoreSubscription' => 'onAfterStoreSubscription', 'onMembershipActive' => 'onMembershipActive', 'onMembershipExpire' => 'onMembershipExpire', 'onSubscriptionAfterSave' => 'onSubscriptionAfterSave', ]; } /** * Render settings from * * @param Event $event * * @return void */ public function onEditSubscriptionPlan(Event $event): void { /* @var OSMembershipTablePlan $row */ [$row] = array_values($event->getArguments()); if (!$this->isExecutable()) { return; } ob_start(); $this->loadLanguage(); $this->drawSettingForm($row); $form = ob_get_contents(); ob_end_clean(); $result = [ 'title' => Text::_('PLG_OSMEMBERSHIP_SCRIPTS'), 'form' => $form, ]; $this->addResult($event, $result); } /** * Store setting into database * * @param Event $event * * @return void */ public function onAfterSaveSubscriptionPlan(Event $event): void { /** * @var string $context * @var OSMembershipTablePlan $row * @var array $data * @var $isNew */ [$context, $row, $data, $isNew] = array_values($event->getArguments()); if (!$this->isExecutable()) { return; } $params = new Registry($row->params); $params->set('subscription_store_script', $data['subscription_store_script']); $params->set('subscription_active_script', $data['subscription_active_script']); $params->set('subscription_expired_script', $data['subscription_expired_script']); $params->set('subscription_update_script', $data['subscription_update_script']); $row->params = $params->toString(); $row->store(); } /** * Run the PHP script when subscription is stored in database * * @param Event $event * * @return void */ public function onAfterStoreSubscription(Event $event): void { /* @var OSMembershipTableSubscriber $row */ [$row] = array_values($event->getArguments()); $params = $this->getPlanParams($row->plan_id); $script = trim($params->get('subscription_store_script', '')); if ($script) { try { eval($script); } catch (Exception $e) { $this->app->enqueueMessage(Text::_('The PHP script is wrong. Please contact Administrator'), 'error'); } } } /** * Run the PHP script when membership is activated * * @param Event $event * * @return void */ public function onMembershipActive(Event $event): void { /* @var OSMembershipTableSubscriber $row */ [$row] = array_values($event->getArguments()); $params = $this->getPlanParams($row->plan_id); $script = trim($params->get('subscription_active_script', '')); if ($script) { try { eval($script); } catch (Exception $e) { $this->app->enqueueMessage(Text::_('The PHP script is wrong. Please contact Administrator'), 'error'); } } } /** * Run the PHP script when membership expired * * @param Event $event * * @return void */ public function onMembershipExpire(Event $event): void { /* @var OSMembershipTableSubscriber $row */ [$row] = array_values($event->getArguments()); $params = $this->getPlanParams($row->plan_id); $script = trim($params->get('subscription_expired_script', '')); if ($script) { try { eval($script); } catch (Exception $e) { $this->app->enqueueMessage(Text::_('The PHP script is wrong. Please contact Administrator'), 'error'); } } } /** * Run the PHP script when membership expired * * @param Event $event * * @return void */ public function onSubscriptionAfterSave(Event $event): void { /* @var OSMembershipTableSubscriber $row */ [$context, $row, $data, $isNew] = array_values($event->getArguments()); $params = $this->getPlanParams($row->plan_id); $script = trim($params->get('subscription_update_script', '')); if ($script) { try { eval($script); } catch (Exception $e) { $this->app->enqueueMessage(Text::_('The PHP script is wrong. Please contact Administrator'), 'error'); } } } /** * Method to check if the plugin is executable * * @return bool */ private function isExecutable() { if ($this->app->isClient('site') && !$this->params->get('show_on_frontend')) { return false; } return true; } /** * Display form allows users to change setting for this subscription plan * * @param object $row */ private function drawSettingForm($row) { require PluginHelper::getLayoutPath($this->_type, $this->_name, 'form'); } /** * The params of the subscription plan * * @param $planId * * @return Registry */ private function getPlanParams($planId) { $db = $this->db; $query = $db->getQuery(true); $query->select('params') ->from('#__osmembership_plans') ->where('id = ' . $planId); $db->setQuery($query); return new Registry($db->loadResult()); } } PK ! 3m�� � userprofile/userprofile.phpnu �[��� <?php /** * @package Joomla * @subpackage Membership Pro * @author Tuan Pham Ngoc * @copyright Copyright (C) 2012 - 2025 Ossolution Team * @license GNU/GPL, see LICENSE.php */ defined('_JEXEC') or die; use Joomla\CMS\Factory; use Joomla\CMS\MVC\Model\BaseDatabaseModel; use Joomla\CMS\Plugin\CMSPlugin; use Joomla\CMS\Plugin\PluginHelper; use Joomla\Database\DatabaseDriver; use Joomla\Event\Event; use Joomla\Event\SubscriberInterface; class plgOSMembershipUserprofile extends CMSPlugin implements SubscriberInterface { /** * Database object. * * @var DatabaseDriver */ protected $db; public static function getSubscribedEvents(): array { return [ 'onAfterStoreSubscription' => 'onAfterStoreSubscription', 'onMembershipActive' => 'onMembershipActive', 'onMembershipUpdate' => 'onMembershipUpdate', 'onProfileUpdate' => 'onProfileUpdate', ]; } /** * Run when a membership stored * * @param Event $event * * @return void */ public function onAfterStoreSubscription(Event $event): void { /* @var OSMembershipTableSubscriber $row */ [$row] = array_values($event->getArguments()); $this->synchronizeProfileData($row, 'onAfterStoreSubscription'); } /** * Plugin triggered when user update his profile * * @param Event $event * * @return void */ public function onProfileUpdate(Event $event): void { /* @var OSMembershipTableSubscriber $row */ [$row] = array_values($event->getArguments()); $this->synchronizeProfileData($row, 'onProfileUpdate'); } /** * Plugin triggered when membership active * * @param Event $event * * @return void */ public function onMembershipActive(Event $event): void { /* @var OSMembershipTableSubscriber $row */ [$row] = array_values($event->getArguments()); $config = OSMembershipHelper::getConfig(); if ($config->create_account_when_membership_active === '1') { $this->synchronizeProfileData($row, 'onMembershipActive'); } } /** * Plugin triggered when user update his profile * * @param Event $event * * @return void */ public function onMembershipUpdate(Event $event): void { /* @var OSMembershipTableSubscriber $row */ [$row] = array_values($event->getArguments()); if ($this->params->get('update_profile_data_when_admin_update_subscription')) { $this->synchronizeProfileData($row, 'onMembershipUpdate'); } } /** * Method to synchronize subscription data from user profile * * @param OSMembershipTableSubscriber $row * @param string $event * * @return void */ private function synchronizeProfileData($row, $event = ''): void { if (!$row->user_id) { return; } // Require library + register autoloader require_once JPATH_ADMINISTRATOR . '/components/com_osmembership/loader.php'; $db = $this->db; $query = $db->getQuery(true); $userId = $row->user_id; // Update Name of users based on first name and last name from profile if ($this->params->get('update_name', 1)) { $user = Factory::getUser((int) $userId); $user->name = rtrim($row->first_name . ' ' . $row->last_name); $user->save(true); } // Get subscribers data if ($event === 'onMembershipUpdate') { $rowFields = OSMembershipHelper::getProfileFields($row->plan_id); } else { $rowFields = OSMembershipHelper::getProfileFields($row->plan_id, true, null, $row->act); } $subscriberData = OSMembershipHelper::getProfileData($row, $row->plan_id, $rowFields); if (!empty($subscriberData['country']) && !empty($subscriberData['state'])) { $subscriberData['state'] = OSMembershipHelper::getStateName( $subscriberData['country'], $subscriberData['state'] ); } $userProfilePluginEnabled = PluginHelper::isEnabled('user', 'profile'); $profileFields = [ 'address1', 'address2', 'city', 'region', 'country', 'postal_code', 'phone', 'website', 'favoritebook', 'aboutme', 'dob', ]; $userFields = OSMembershipHelper::getUserFields(); $userFieldsName = array_keys($userFields); $profileFieldsMapping = []; $userFieldsMapping = []; foreach ($rowFields as $rowField) { if (!$rowField->profile_field_mapping) { continue; } if ($userProfilePluginEnabled && in_array($rowField->profile_field_mapping, $profileFields)) { $profileFieldsMapping[$rowField->profile_field_mapping] = $rowField->name; continue; } if (in_array($rowField->profile_field_mapping, $userFieldsName)) { $userFieldsMapping[$rowField->profile_field_mapping] = $rowField->name; } } // Store user profile data if (count($profileFieldsMapping) > 0) { //Delete old profile data $fields = $keys = array_keys($profileFieldsMapping); for ($i = 0, $n = count($keys); $i < $n; $i++) { $keys[$i] = 'profile.' . $keys[$i]; } $query->delete('#__user_profiles') ->where('user_id = ' . $userId) ->where('profile_key IN (' . implode(',', $db->quote($keys)) . ')'); $db->setQuery($query); $db->execute(); $order = 1; $query->clear() ->insert('#__user_profiles'); foreach ($fields as $field) { $fieldMapping = $profileFieldsMapping[$field]; if (isset($subscriberData[$fieldMapping])) { $value = $subscriberData[$fieldMapping]; } else { $value = ''; } $query->values(implode(',', $db->quote([$userId, 'profile.' . $field, json_encode($value), $order++]))); } $db->setQuery($query); $db->execute(); } if (count($userFields) > 0) { BaseDatabaseModel::addIncludePath(JPATH_ADMINISTRATOR . '/components/com_fields/models', 'FieldsModel'); /* @var FieldsModelField $model */ $model = BaseDatabaseModel::getInstance('Field', 'FieldsModel', ['ignore_request' => true]); foreach ($userFields as $field) { $fieldName = $field->name; if (isset($userFieldsMapping[$fieldName])) { $fieldMapping = $userFieldsMapping[$fieldName]; $fieldValue = $subscriberData[$fieldMapping] ?? ''; if (is_string($fieldValue) && is_array(json_decode($fieldValue))) { $fieldValue = json_decode($fieldValue); } $model->setFieldValue($field->id, $userId, $fieldValue); } } } } } PK ! C_��� � userprofile/userprofile.xmlnu �[��� <?xml version="1.0" encoding="utf-8"?> <extension version="4.2.0" type="plugin" group="osmembership" method="upgrade"> <name>Membership Pro - Userprofile</name> <author>Tuan Pham Ngoc</author> <authorEmail>tuanpn@joomdonation.com</authorEmail> <authorUrl>https://joomdonation.com</authorUrl> <copyright>Copyright (C) 2012 - 2025 Ossolution Team</copyright> <license>GNU General Public License version 3, or later</license> <creationDate>Nov 2012</creationDate> <version>4.3.1</version> <description>This plugin is used to Add Subscribers to Userprofile when they subscribe for a subscription plan. </description> <files> <filename plugin="userprofile">userprofile.php</filename> </files> <config> <fields name="params"> <fieldset name="basic"> <field name="update_profile_data_when_admin_update_subscription" type="radio" label="Update User Profile When Admin Update A Subscription" description="If set to Yes, the system will update user profile data when admin update a subscription record from backend" default="0" > <option value="1">JYES</option> <option value="0">JNO</option> </field> <field name="update_name" type="radio" label="Update Name Of User" description="If you do not want the plugin to update name of user base on data from first_name and last_name, set this parameter to No" default="1" > <option value="1">JYES</option> <option value="0">JNO</option> </field> </fieldset> </fields> </config> </extension> PK ! V<��} } userfiles/userfiles.xmlnu �[��� <?xml version="1.0" encoding="utf-8"?> <extension version="4.2.0" type="plugin" group="osmembership" method="upgrade"> <name>Membership Pro - User Files</name> <author>Tuan Pham Ngoc</author> <authorEmail>tuanpn@joomdonation.com</authorEmail> <authorUrl>https://joomdonation.com</authorUrl> <copyright>Copyright (C) 2012 - 2025 Ossolution Team</copyright> <license>GNU General Public License version 3, or later</license> <creationDate>Nov 2012</creationDate> <version>4.3.1</version> <description>This plugin is used to display files which administrator want to give individual users to download. These files need to be uploaded manually to media/com_osmembership/userfiles/username or media/com_osmembership/userfiles/userid folder (replace username and userid with the username and id of the individual subscriber)</description> <files> <filename plugin="userfiles">userfiles.php</filename> <folder>tmpl</folder> </files> <config> <fields name="params"> <fieldset name="basic"> <field name="sort_direction" type="list" label="Short Files Direction" description="Choose to sort files base on filename in ASC or DESC order" class="btn-group btn-group-yesno" default="0" > <option value="0">ASC</option> <option value="1">DESC</option> </field> </fieldset> </fields> </config> </extension>PK ! ���Q� � userfiles/userfiles.phpnu �[��� <?php /** * @package Joomla * @subpackage Membership Pro * @author Tuan Pham Ngoc * @copyright Copyright (C) 2012 - 2025 Ossolution Team * @license GNU/GPL, see LICENSE.php */ defined('_JEXEC') or die; use Joomla\CMS\Language\Text; use Joomla\CMS\Plugin\CMSPlugin; use Joomla\CMS\Plugin\PluginHelper; use Joomla\Event\Event; use Joomla\Event\SubscriberInterface; class plgOSMembershipUserfiles extends CMSPlugin implements SubscriberInterface { use MPFEventResult; /** * Application object. * * @var \Joomla\CMS\Application\CMSApplication */ protected $app; public static function getSubscribedEvents(): array { return [ 'onProfileDisplay' => 'onProfileDisplay', ]; } /** * Render setting form * * @param Event $event * * @return void */ public function onProfileDisplay(Event $event): void { /* @var OSMembershipTableSubscriber $row */ [$row] = array_values($event->getArguments()); ob_start(); $this->drawFiles($row); $form = ob_get_contents(); ob_end_clean(); $result = [ 'title' => Text::_('OSM_MY_FILES'), 'form' => $form, ]; $this->addResult($event, $result); } /** * Display Display List of Documents which the current subscriber can download from his subscription * * @param object $row */ private function drawFiles($row) { JLoader::register('OSMembershipModelUserfiles', JPATH_ROOT . '/components/com_osmembership/model/userfiles.php'); /* @var OSMembershipModelUserfiles $model */ $model = MPFModel::getTempInstance('Userfiles', 'OSMembershipModel'); [$path, $files] = $model->getData(); if ($this->params->get('sort_direction')) { rsort($files); } $Itemid = $this->app->getInput()->getInt('Itemid'); require PluginHelper::getLayoutPath($this->_type, $this->_name, 'default'); } } PK ! pJ�%P P userfiles/tmpl/default.phpnu �[��� <?php /** * @package Joomla * @subpackage Membership Pro * @author Tuan Pham Ngoc * @copyright Copyright (C) 2012 - 2025 Ossolution Team * @license GNU/GPL, see LICENSE.php */ defined('_JEXEC') or die; use Joomla\CMS\Language\Text; use Joomla\CMS\Router\Route; /** * Layout variables * ----------------- * @var array $files * @var string $path * @var int $Itemid */ $bootstrapHelper = OSMembershipHelperBootstrap::getInstance(); $centerClass = $bootstrapHelper->getClassMapping('center'); ?> <table class="adminlist <?php echo $bootstrapHelper->getClassMapping('table table-striped table-bordered'); ?>" id="adminForm"> <thead> <tr> <th class="title"><?php echo Text::_('OSM_FILE'); ?></th> <th class="<?php echo $centerClass; ?>"><?php echo Text::_('OSM_SIZE'); ?></th> <th class="<?php echo $centerClass; ?>"><?php echo Text::_('OSM_DOWNLOAD'); ?></th> </tr> </thead> <tbody> <?php foreach ($files as $file) { $downloadLink = Route::_('index.php?option=com_osmembership&task=download_user_file&file=' . $file . '&Itemid=' . $Itemid); ?> <tr> <td><a href="<?php echo $downloadLink ?>"><?php echo $file; ?></a></td> <td class="<?php echo $centerClass; ?>"><?php echo OSMembershipHelperHtml::getFormattedFilezize($path . '/' . $file); ?></td> <td class="<?php echo $centerClass; ?>"> <a href="<?php echo $downloadLink; ?>"><i class="<?php echo $bootstrapHelper->getClassMapping('icon-download'); ?>"></i></a> </td> </tr> <?php } ?> </tbody> </table> PK ! 9�_�o o # groupmembership/groupmembership.phpnu �[��� <?php /** * @package Joomla * @subpackage Membership Pro * @author Tuan Pham Ngoc * @copyright Copyright (C) 2012 - 2025 Ossolution Team * @license GNU/GPL, see LICENSE.php */ defined('_JEXEC') or die; use Joomla\CMS\Factory; use Joomla\CMS\Language\Text; use Joomla\CMS\Plugin\CMSPlugin; use Joomla\CMS\Plugin\PluginHelper; use Joomla\Event\Event; use Joomla\Event\SubscriberInterface; use OSSolution\MembershipPro\Admin\Event\Subscription\MembershipActive; use OSSolution\MembershipPro\Admin\Event\Subscription\MembershipExpire; class plgOSMembershipGroupmembership extends CMSPlugin implements SubscriberInterface { use MPFEventResult; /** * The application object * * @var \Joomla\CMS\Application\CMSApplication */ protected $app; /** * Database object. * * @var \Joomla\Database\DatabaseDriver */ protected $db; public static function getSubscribedEvents(): array { return [ 'onMembershipActive' => 'onMembershipActive', 'onMembershipExpire' => 'onMembershipExpire', 'onProfileDisplay' => 'onProfileDisplay', ]; } /** * Run when a membership activated * * @param Event $event * * @return void */ public function onMembershipActive(Event $event): void { /* @var OSMembershipTableSubscriber $row */ [$row] = array_values($event->getArguments()); if ($row->user_id && !$row->group_admin_id) { // Change subscription end date of the group members $db = $this->db; $query = $db->getQuery(true) ->select('MAX(to_date)') ->from('#__osmembership_subscribers') ->where('user_id=' . $row->user_id . ' AND plan_id=' . $row->plan_id . ' AND published = 1'); $db->setQuery($query); $maxToDate = $db->loadResult(); if ($maxToDate) { $query->clear() ->update('#__osmembership_subscribers') ->set('published = 1') ->set('to_date = ' . $db->quote($maxToDate)) ->where('group_admin_id = ' . $row->user_id) ->where('plan_id = ' . $row->plan_id); $db->setQuery($query); $db->execute(); // Need to trigger onMembershipActive event $query->clear() ->select('id') ->from('#__osmembership_subscribers') ->where('plan_id = ' . $row->plan_id) ->where('group_admin_id = ' . $row->user_id); $db->setQuery($query); $groupMemberIds = $db->loadColumn(); if (count($groupMemberIds)) { $app = Factory::getApplication(); foreach ($groupMemberIds as $groupMemberId) { $groupMember = new OSMembershipTableSubscriber($db); $groupMember->load($groupMemberId); $event = new MembershipActive(['row' => $groupMember]); $app->triggerEvent($event->getName(), $event); } // Update subscription status to active, just in case they were marked as expired before for some reasons $query->clear() ->update('#__osmembership_subscribers') ->set('published = 1') ->where('plan_id = ' . $row->plan_id) ->where('group_admin_id = ' . $row->user_id); $db->setQuery($query); $db->execute(); } } if ($row->act == 'upgrade') { // Process upgrade group members to new membership $fromPlan = OSMembershipHelperDatabase::getPlan($row->from_plan_id); $toPlan = OSMembershipHelperDatabase::getPlan($row->plan_id); if ($fromPlan->number_group_members > 0 && $toPlan->number_group_members > 0) { // Get all group members of old plan $query->clear() ->select('id') ->from('#__osmembership_subscribers') ->where('plan_id = ' . (int) $row->from_plan_id) ->where('group_admin_id = ' . $row->user_id); $db->setQuery($query); $groupMemberIds = $db->loadColumn(); if (count($groupMemberIds)) { $app = Factory::getApplication(); foreach ($groupMemberIds as $groupMemberId) { $groupMember = new OSMembershipTableSubscriber($db); $groupMember->load($groupMemberId); $groupMember->plan_id = $row->plan_id; $groupMember->from_date = $row->from_date; $groupMember->to_date = $row->to_date; $groupMember->published = 1; $groupMember->store(); $event = new MembershipActive(['row' => $groupMember]); $app->triggerEvent($event->getName(), $event); } } } } } } /** * Run when a membership expired die * * @param Event $event * * @return void */ public function onMembershipExpire(Event $event): void { /* @var OSMembershipTableSubscriber $row */ [$row] = array_values($event->getArguments()); if ($row->user_id && !$row->group_admin_id) { $db = $this->db; $query = $db->getQuery(true) ->select('COUNT(*)') ->from('#__osmembership_subscribers') ->where('published = 1') ->where('plan_id = ' . $row->plan_id) ->where('user_id = ' . $row->user_id); $db->setQuery($query); $total = (int) $db->loadResult(); if (!$total) { // Expired subscription, so need to trigger all group members as expired $query->clear() ->select('id') ->from('#__osmembership_subscribers') ->where('plan_id = ' . $row->plan_id) ->where('group_admin_id = ' . $row->user_id); $db->setQuery($query); $groupMemberIds = $db->loadColumn(); if (count($groupMemberIds)) { $app = Factory::getApplication(); foreach ($groupMemberIds as $groupMemberId) { $groupMember = new OSMembershipTableSubscriber($db); $groupMember->load($groupMemberId); $event = new MembershipExpire(['row' => $groupMember]); $app->triggerEvent($event->getName(), $event); } // Need to mark the subscription as expired $query->clear() ->update('#__osmembership_subscribers') ->set('published = 2') ->where('plan_id = ' . $row->plan_id) ->where('group_admin_id = ' . $row->user_id); $db->setQuery($query); $db->execute(); } } } } /** * Render setting form * * @param Event $event * * @return void */ public function onProfileDisplay(Event $event): void { // Only show this tab on user profile page frontend if (!$this->app->isClient('site')) { return; } if (!$this->params->get('show_group_members_on_profile')) { return; } /* @var OSMembershipTableSubscriber $row */ [$row] = array_values($event->getArguments()); ob_start(); $this->showGroupMembers($row); $form = ob_get_contents(); ob_end_clean(); $result = [ 'title' => Text::_('OSM_GROUP_MEMBERS_LIST'), 'form' => $form, ]; $this->addResult($event, $result); } /** * @param OSMembershipTableSubscriber $row * * @return void */ private function showGroupMembers($row) { JLoader::register('OSMembershipModelGroupmembers', JPATH_ROOT . '/components/com_osmembership/model/groupmembers.php'); /* @var OSMembershipModelGroupmembers $model */ $model = MPFModel::getTempInstance('Groupmembers', 'OSMembershipModel'); $model->setGroupAdminUserId($row->user_id); $rowMembers = $model->getData(); if (count($rowMembers) === 0) { return; } $fields = OSMembershipHelper::getProfileFields(0, true); foreach ($fields as $i => $field) { if (!$field->show_on_subscriptions) { unset($fields[$i]); } } $fieldsData = $model->getFieldsData(); $Itemid = OSMembershipHelperRoute::getViewRoute('groupmembers', $this->app->getInput()->getInt('Itemid')); require PluginHelper::getLayoutPath($this->_type, $this->_name, 'members'); } } PK ! Q���& & groupmembership/tmpl/members.phpnu �[��� <?php /** * @package Joomla * @subpackage Membership Pro * @author Tuan Pham Ngoc * @copyright Copyright (C) 2012 - 2025 Ossolution Team * @license GNU/GPL, see LICENSE.php */ defined('_JEXEC') or die; use Joomla\CMS\HTML\HTMLHelper; use Joomla\CMS\Language\Text; use Joomla\CMS\Router\Route; $bootstrapHelper = OSMembershipHelperBootstrap::getInstance(); $config = OSMembershipHelper::getConfig(); /** * @var array $rowMembers * @var array $fields * @var array $fieldsData * @var int $Itemid */ $rowFluidClass = $bootstrapHelper->getClassMapping('row-fluid'); $clearFixClass = $bootstrapHelper->getClassMapping('clearfix'); $centerClass = $bootstrapHelper->getClassMapping('center'); $cols = count($fields) + 3; ?> <table class="<?php echo $bootstrapHelper->getClassMapping('table table-striped table-bordered table-hover'); ?>"> <thead> <tr> <th><?php echo Text::_('OSM_PLAN'); ?></th> <th><?php echo Text::_('OSM_USERNAME'); ?></th> <?php foreach($fields as $field) { ?> <th><?php echo $field->title; ?></th> <?php } if ($config->auto_generate_membership_id) { $cols++ ; ?> <th width="8%" class="<?php echo $centerClass; ?>"> <?php echo Text::_('OSM_MEMBERSHIP_ID'); ?> </th> <?php } ?> <th class="<?php echo $centerClass; ?>"> <?php echo Text::_('OSM_CREATED_DATE') ; ?> </th> </tr> </thead> <tbody> <?php for ($i = 0 , $n = count($rowMembers) ; $i < $n ; $i++) { $rowMember = $rowMembers[$i]; $link = Route::_('index.php?option=com_osmembership&view=groupmember&id=' . $rowMember->id . '&Itemid=' . $Itemid); ?> <tr> <td> <a href="<?php echo $link; ?>"><?php echo $rowMember->plan_title;?></a> </td> <td> <?php echo $rowMember->username; ?> </td> <?php foreach ($fields as $field) { ?> <td> <?php if ($field->is_core) { echo $rowMember->{$field->name}; } else { echo $fieldsData[$rowMember->id][$field->id] ?? ''; } ?> </td> <?php } if ($config->auto_generate_membership_id) { ?> <td class="<?php echo $centerClass; ?>"> <?php echo $rowMember->membership_id ? OSMembershipHelper::formatMembershipId($rowMember, $config) : ''; ?> </td> <?php } ?> <td class="<?php echo $centerClass; ?>"> <?php echo HTMLHelper::_('date', $rowMember->created_date, $config->date_format); ?> </td> </tr> <?php } ?> </tbody> </table> PK ! Y�M� � # groupmembership/groupmembership.xmlnu �[��� <?xml version="1.0" encoding="utf-8"?> <extension version="4.2.0" type="plugin" group="osmembership" method="upgrade"> <name>Membership Pro - Group Membership Plugin</name> <author>Tuan Pham Ngoc</author> <authorEmail>tuanpn@joomdonation.com</authorEmail> <authorUrl>https://joomdonation.com</authorUrl> <copyright>Copyright (C) 2012 - 2025 Ossolution Team</copyright> <license>GNU General Public License version 3, or later</license> <creationDate>Nov 2012</creationDate> <version>4.3.1</version> <description>This plugin is used to handle group membership feature in Membership Pro</description> <files> <filename plugin="groupmembership">groupmembership.php</filename> <folder>tmpl</folder> </files> <config> <fields name="params"> <fieldset name="basic"> <field name="exclude_group_ids" type="Usergrouplist" multiple="true" default="7,8" layout="joomla.form.field.list-fancy-select" label="Exclude User Groups" description="By default, group members will have same Joomla user groups with group admin. If you want group members to be excluded from certain user groups, select these user groups here"/> <field name="show_group_members_on_profile" type="radio" label="Show Group Members On Profile Page" description="Set to Yes if you want to show group members on user profile page of group admin" class="btn-group btn-group-yesno" default="0" > <option value="1">JYES</option> <option value="0">JNO</option> </field> </fieldset> </fields> </config> </extension>PK ! �!00B B acym/acym.xmlnu �[��� <?xml version="1.0" encoding="utf-8"?> <extension version="4.2.0" type="plugin" group="osmembership" method="upgrade"> <name>Membership Pro - AcyMailing</name> <author>Tuan Pham Ngoc</author> <authorEmail>tuanpn@joomdonation.com</authorEmail> <authorUrl>https://joomdonation.com</authorUrl> <copyright>Copyright (C) 2012 - 2025 Ossolution Team</copyright> <license>GNU General Public License version 3, or later</license> <creationDate>Feb 2019</creationDate> <version>4.3.1</version> <description>This plugin is used to Add Subscribers to AcyMailing 6 and ACYMailing 7 when they subscribe for a subscription plan. </description> <files> <filename plugin="acym">acym.php</filename> <folder>tmpl</folder> </files> <languages folder="language"> <language tag="en-GB">en-GB/en-GB.plg_osmembership_acym.ini</language> </languages> <config> <fields name="params"> <fieldset name="basic"> <field name="subscribe_group_members" type="radio" label="Subscribe Group Members" description="If set to No, group members won't be subscribed to ACYMailing" class="btn-group btn-group-yesno" default="1" > <option value="1">JYES</option> <option value="0">JNO</option> </field> <field name="show_on_frontend" type="radio" label="Show On Frontend" description="If set to Yes, this plugin will be available on frontend add/edit plan form" class="btn-group btn-group-yesno" default="0" > <option value="1">JYES</option> <option value="0">JNO</option> </field> </fieldset> </fields> </config> </extension>PK ! ��_�K<