widgetName = JText::translate('VBO_W_DOORACCESSCONTROL_TITLE'); $this->widgetDescr = JText::translate('VBO_W_DOORACCESSCONTROL_DESCR'); $this->widgetId = basename(__FILE__, '.php'); $this->widgetIcon = ''; $this->widgetStyleName = 'orange'; // load widget's settings $this->widgetSettings = (array) $this->loadSettings(); } /** * @inheritDoc */ public function preflight() { if (!JFactory::getUser()->authorise('core.vbo.pms', 'com_vikbooking')) { // insufficient user capabilities return false; } return parent::preflight(); } /** * @inheritDoc */ public function preload() { // load assets $this->vbo_app->loadSelect2(); } /** * @inheritDoc */ public function getWidgetDetails() { // get common widget details from parent abstract class $details = parent::getWidgetDetails(); // append the modal rendering information $details['modal'] = [ 'add_class' => 'vbo-modal-nopadding vbo-modal-large', ]; return $details; } /** * @inheritDoc */ public function render(?VBOMultitaskData $data = null) { // increase widget's instance counter static::$instance_counter++; // check whether the widget is being rendered via AJAX when adding it through the customizer $is_ajax = $this->isAjaxRendering(); // generate a unique ID for the sticky notes wrapper instance $wrapper_instance = !$is_ajax ? static::$instance_counter : rand(); $wrapper_id = 'vbo-widget-door-access-control-' . $wrapper_instance; // default provider, profile and device values (profile and device start from null) $defaultProvider = $this->widgetSettings['id_provider'] ?? null; $defaultProfile = null; $defaultDevice = null; $defaultTab = null; // check for multitask data values $js_intvals_id = ''; if ($data) { // access Multitask data if ($data->isModalRendering()) { // get modal JS identifier $js_intvals_id = $data->getModalJsIdentifier(); } // check if provider, profile, device or tab values were set $defaultProvider = $this->getOption('provider') ?: $data->get('provider') ?: $defaultProvider; $defaultProfile = $this->getOption('profile') ?: $data->get('profile') ?: $defaultProfile; $defaultDevice = $this->getOption('device') ?: $data->get('device') ?: $defaultDevice; $defaultTab = $this->getOption('tab') ?: $data->get('tab') ?: $defaultTab; } // access the door access factory object $factory = VBOFactory::getDoorAccessControl(); // load the list of available integration providers $providers = $factory->getIntegrationProviders($assoc = true); if (!$providers) { // abort return; } ?>

widgetIcon; ?> widgetName; ?>

input->getString('wrapper', ''); $provider = $app->input->getString('provider', ''); $profile = $app->input->getUInt('profile', 0); $id_device = $app->input->getString('id_device', ''); $tab = $app->input->getString('tab', ''); if (empty($provider)) { VBOHttpDocument::getInstance($app)->close(400, 'Missing door access control provider identifier.'); } // access the door access factory object $factory = VBOFactory::getDoorAccessControl(); // get the requested integration provider $integration = $factory->getIntegrationProvider($provider); if (!$integration) { VBOHttpDocument::getInstance($app)->close(404, 'Invalid door access control provider identifier.'); } if (empty($this->widgetSettings['id_provider']) || $this->widgetSettings['id_provider'] != $integration->getAlias()) { // set provider alias in widget settings $this->widgetSettings['id_provider'] = $integration->getAlias(); // set no active profile in widget settings $this->widgetSettings['id_profile'] = null; // set no active device in widget settings $this->widgetSettings['id_device'] = null; } // determine the optional profile ID to get, if any $idProfile = (int) ($profile ?: $this->widgetSettings['id_profile'] ?? 0); // load the active integration profiles, if any $profiles = $factory->loadIntegrationRecords($integration->getAlias(), $idProfile); if ($profiles) { if ($profiles[0]['id'] != ($this->widgetSettings['id_profile'] ?? null)) { // set no active device in widget settings $this->widgetSettings['id_device'] = null; } // set active profile in widget settings $this->widgetSettings['id_profile'] = $profiles[0]['id']; // inject first profile record within the integration $integration->setProfileRecord($profiles[0]); } // determine the optional device ID to get, if any $loadIdDevice = (string) ($id_device ?: $this->widgetSettings['id_device'] ?? ''); // ensure the device ID exists within the current profile record if ($loadIdDevice && !$integration->deviceExists($loadIdDevice)) { // invalid device ID $loadIdDevice = ''; } if ($loadIdDevice) { // set active device in widget settings $this->widgetSettings['id_device'] = $loadIdDevice; } // update widget settings $this->updateSettings(json_encode($this->widgetSettings)); // access the integration icon $integrationIcon = $integration->getIcon() ?: ''; // determine the active tab to display $hasParams = (bool) count($integration->getParams()); $hasSettings = (bool) count($integration->getSettings()); $hasDevices = (bool) count($integration->getDevices()); if ($hasParams && !$hasSettings) { // default to settings tab $activeTab = 'settings'; } elseif ($hasSettings && !$hasDevices) { // default to devices tab $activeTab = 'devices'; } else { // default to dashboard tab $activeTab = 'dashboard'; } $activeTab = $tab ?: $activeTab; // load all listing names and related IDs $listingsPool = VikBooking::getAvailabilityInstance(true)->loadRooms([], 0, true); $listingsPool = array_combine(array_column($listingsPool, 'id'), array_column($listingsPool, 'name')); // start output buffering ob_start(); ?>
getIcon(); $icon = $icon && !preg_match('/^http/', (string) $icon) ? $icon : ''; return [ 'id' => $device->getID(), 'name' => sprintf('%s (%s)', $device->getName(), $device->getID()), 'html' => $icon, ]; }, $integration->getDevices()); ?>
renderElementsDropDown([ 'placeholder' => JText::translate('VBTRKDEVICE'), 'attributes' => [ 'class' => 'vbo-door-access-control-device-id', 'onchange' => 'vboWidgetDACSwitchDeviceID("' . $wrapper . '")', ], 'selected_value' => $loadIdDevice, 'style_selection' => true, 'default_selection_icon' => VikBookingIcons::i('fingerprint'), ], $deviceElements); ?>
getDeviceById($loadIdDevice); // iterate all device capabilities foreach ($integrationDevice->getCapabilities() as $cap) { $capIcon = (string) $cap->getIcon(); $isHtmlIcon = false; ?>
getTitle(); ?>
getDescription(); ?>
getCallback()) { ?>

: 0

getDevices()); ?>
getDevices() as $device) { $deviceIcon = $device->getIcon(); ?>
'; } ?>
getName(); ?>
getID(); ?> getModel() || $device->getDescription()) { ?> getModel(), $device->getDescription()])); ?>
getBatteryLevel() !== null) { if ($device->getBatteryLevel() > 65) { $battery_class = 'success'; } elseif ($device->getBatteryLevel() > 35) { $battery_class = 'warning'; } else { $battery_class = 'error'; } ?>
getBatteryLevel()); ?>%
(countConnectedListings(); ?>)
getConnectedListings() as $listingId) { // check if the listing was connected at subunit-level $listingSubunitIds = $device->getConnectedListingSubunits($listingId); if ($listingSubunitIds) { // display only the listing subunit connections foreach ($listingSubunitIds as $subunitId) { ?>
widgetSettings['id_profile'])) { ?>
getParams(), $integration->getSettings() )->setInputName('integration[' . $integration->getAlias() . ']')->getHtml(); ?>
 
$html_content, 'tot_profiles' => count($profiles), ]; } /** * Custom method for this widget only. * Saves or updates the settings for a given provider and profile. * * @return array */ public function saveProviderSettings() { $app = JFactory::getApplication(); $wrapper = $app->input->getString('wrapper', ''); $profile = $app->input->get('profile', [], 'array'); $settings = $app->input->get('settings', [], 'array'); if (empty($profile['id_provider'])) { VBOHttpDocument::getInstance($app)->close(400, 'Missing door access control provider identifier for saving the settings.'); } // access the door access factory object $factory = VBOFactory::getDoorAccessControl(); // get the requested integration provider $integration = $factory->getIntegrationProvider($profile['id_provider']); if (!$integration) { VBOHttpDocument::getInstance($app)->close(404, 'Invalid door access control provider identifier.'); } // determine if we are updating an existing profile ID or if we are creating a new one (0 or -1) $idProfile = (int) ($profile['id_profile'] ?? 0); $idProfile = $idProfile > 0 ? $idProfile : 0; // normalize default provider settings $defaultSettings = array_combine(array_keys($integration->getParams()), array_map(function($paramName) { // param settings will get an empty string by default to support checkbox or other param types return ''; }, array_keys($integration->getParams()))); // build record options $recordOptions = [ 'id_profile' => $idProfile, 'profile_name' => $profile['profile_name'] ?? '', 'gentype' => $profile['gentype'] ?? null, 'genperiod' => $profile['genperiod'] ?? null, 'settings' => array_merge($defaultSettings, $settings), ]; try { // save or update the integration record name and settings $factory->saveIntegrationRecord($integration, $recordOptions); } catch (Exception $e) { VBOHttpDocument::getInstance($app)->close($e->getCode() ?: 500, $e->getMessage() ?: 'Error saving provider settings.'); } return [ 'id_profile' => $integration->getProfileID(), ]; } /** * Custom method for this widget only. * Fetches the remote provider devices and saves them internally. * * @return array */ public function updateProviderDevices() { $app = JFactory::getApplication(); $wrapper = $app->input->getString('wrapper', ''); $provider = $app->input->getString('provider', ''); $idProfile = $app->input->getUInt('profile', 0); if (empty($provider)) { VBOHttpDocument::getInstance($app)->close(400, 'Missing door access control provider identifier.'); } // access the door access factory object $factory = VBOFactory::getDoorAccessControl(); // get the requested integration provider $integration = $factory->getIntegrationProvider($provider); if (!$integration) { VBOHttpDocument::getInstance($app)->close(404, 'Invalid door access control provider identifier.'); } // load the requested integration profile $profile = $factory->loadIntegrationRecord($idProfile); if (!$profile) { VBOHttpDocument::getInstance($app)->close(404, 'Invalid door access control profile identifier.'); } // inject profile record within the integration $integration->setProfileRecord($profile); try { // fetch and update the provider devices $tot_devices = $factory->updateProviderDevices($integration); } catch (Exception $e) { // raise an error VBOHttpDocument::getInstance($app)->close($e->getCode() ?: 500, $e->getMessage()); } return [ 'tot_devices' => $tot_devices, ]; } /** * Custom method for this widget only. * Adds a new listing ID connection with a device. * * @return array */ public function setDeviceListingConnection() { $app = JFactory::getApplication(); $wrapper = $app->input->getString('wrapper', ''); $provider = $app->input->getString('provider', ''); $idProfile = $app->input->getUInt('profile', 0); $idDevice = $app->input->getString('device', ''); $idListing = $app->input->getUInt('listing', 0); $idSubunit = $app->input->getUInt('subunit', 0); if (empty($provider)) { VBOHttpDocument::getInstance($app)->close(400, 'Missing door access control provider identifier.'); } if (empty($idDevice)) { VBOHttpDocument::getInstance($app)->close(400, 'Missing door access control device identifier.'); } if (empty($idListing)) { VBOHttpDocument::getInstance($app)->close(400, 'Missing listing ID.'); } // access the door access factory object $factory = VBOFactory::getDoorAccessControl(); // get the requested integration provider $integration = $factory->getIntegrationProvider($provider); if (!$integration) { VBOHttpDocument::getInstance($app)->close(404, 'Invalid door access control provider identifier.'); } // load the requested integration profile $profile = $factory->loadIntegrationRecord($idProfile); if (!$profile) { VBOHttpDocument::getInstance($app)->close(404, 'Invalid door access control profile identifier.'); } // inject profile record within the integration $integration->setProfileRecord($profile); // attempt to find the requested device $deviceFound = null; foreach ($integration->getDevices() as $device) { if ($device->getID() === $idDevice) { // device ID found, add listing relation $device->addConnectedListing($idListing, $idSubunit); // turn flag on and abort $deviceFound = $device; break; } } if (!$deviceFound) { VBOHttpDocument::getInstance($app)->close(400, 'Invalid door access control device identifier.'); } try { // update the integration record devices $integration->setProfileRecordProp('devices', $integration->getDevices()); // ensure the required device-listing relation is saved on E4jConnect first if (!class_exists('VCMDacDevicesRequestor')) { throw new Exception('Please update the Channel Manager.', 426); } (new VCMDacDevicesRequestor)->add($deviceFound); // update integration devices onto the current profile record $factory->saveIntegrationRecord($integration, ['devices' => $integration->getDevices()]); } catch (Exception $e) { // raise an error VBOHttpDocument::getInstance($app)->close($e->getCode() ?: 500, $e->getMessage()); } return [ 'device_name' => $deviceFound->getName(), ]; } /** * Custom method for this widget only. * Removes an existing listing ID connection with a device. * * @return array */ public function unsetDeviceListingConnection() { $app = JFactory::getApplication(); $wrapper = $app->input->getString('wrapper', ''); $provider = $app->input->getString('provider', ''); $idProfile = $app->input->getUInt('profile', 0); $idDevice = $app->input->getString('device', ''); $idListing = $app->input->getUInt('listing', 0); $idSubunit = $app->input->getUInt('subunit', 0); if (empty($provider)) { VBOHttpDocument::getInstance($app)->close(400, 'Missing door access control provider identifier.'); } if (empty($idDevice)) { VBOHttpDocument::getInstance($app)->close(400, 'Missing door access control device identifier.'); } if (empty($idListing)) { VBOHttpDocument::getInstance($app)->close(400, 'Missing listing ID.'); } // access the door access factory object $factory = VBOFactory::getDoorAccessControl(); // get the requested integration provider $integration = $factory->getIntegrationProvider($provider); if (!$integration) { VBOHttpDocument::getInstance($app)->close(404, 'Invalid door access control provider identifier.'); } // load the requested integration profile $profile = $factory->loadIntegrationRecord($idProfile); if (!$profile) { VBOHttpDocument::getInstance($app)->close(404, 'Invalid door access control profile identifier.'); } // inject profile record within the integration $integration->setProfileRecord($profile); // attempt to find the requested device ID $deviceFound = null; foreach ($integration->getDevices() as $device) { if ($device->getID() === $idDevice) { // device ID found, remove listing relation $device->removeConnectedListing($idListing, $idSubunit); // turn flag on and abort $deviceFound = $device; break; } } if (!$deviceFound) { VBOHttpDocument::getInstance($app)->close(400, 'Invalid door access control device identifier.'); } try { // update the integration record devices $integration->setProfileRecordProp('devices', $integration->getDevices()); if (!$deviceFound->getConnectedListings()) { // ensure the device is deleted from E4jConnect when no more listings are connected if (!class_exists('VCMDacDevicesRequestor')) { throw new Exception('Please update the Channel Manager.', 426); } (new VCMDacDevicesRequestor)->delete($deviceFound); } // update integration devices onto the current profile record $factory->saveIntegrationRecord($integration, ['devices' => $integration->getDevices()]); } catch (Exception $e) { // raise an error VBOHttpDocument::getInstance($app)->close($e->getCode() ?: 500, $e->getMessage()); } return [ 'device_name' => $deviceFound->getName(), ]; } /** * Custom method for this widget only. * Deletes a specific integration profile record. * * @return array */ public function deleteProfileRecord() { $app = JFactory::getApplication(); $wrapper = $app->input->getString('wrapper', ''); $provider = $app->input->getString('provider', ''); $idProfile = $app->input->getUInt('profile', 0); if (empty($provider)) { VBOHttpDocument::getInstance($app)->close(400, 'Missing door access control provider identifier.'); } // access the door access factory object $factory = VBOFactory::getDoorAccessControl(); // get the requested integration provider $integration = $factory->getIntegrationProvider($provider); if (!$integration) { VBOHttpDocument::getInstance($app)->close(404, 'Invalid door access control provider identifier.'); } // load the requested integration profile $profile = $factory->loadIntegrationRecord($idProfile); if (!$profile) { VBOHttpDocument::getInstance($app)->close(404, 'Invalid door access control profile identifier.'); } // inject profile record within the integration $integration->setProfileRecord($profile); try { // ensure all devices are deleted from E4jConnect first if (!class_exists('VCMDacDevicesRequestor')) { throw new Exception('Please update the Channel Manager.', 426); } (new VCMDacDevicesRequestor)->delete($integration->getDevices()); // destroy (delete) the current profile record $integration->destroyProfileRecord(); // set no active profile in widget settings $this->widgetSettings['id_profile'] = null; // set no active device in widget settings $this->widgetSettings['id_device'] = null; // update widget settings $this->updateSettings(json_encode($this->widgetSettings)); } catch (Exception $e) { VBOHttpDocument::getInstance($app)->close($e->getCode() ?: 500, $e->getMessage()); } // process successfully completed return [ 'success' => 1, ]; } /** * Custom method for this widget only. * Executes a capability for a specific device. * * @return array */ public function executeDeviceCapability() { $app = JFactory::getApplication(); $wrapper = $app->input->getString('wrapper', ''); $provider = $app->input->getString('provider', ''); $idProfile = $app->input->getUInt('profile', 0); $idDevice = $app->input->getString('device', ''); $idCapability = $app->input->getString('capability', ''); $noParams = $app->input->getBool('noparams', false); $capabilitySettings = $app->input->get('capability_settings', [], 'array'); $retryDataOptions = $app->input->get('retry_data', [], 'array'); if (empty($provider)) { VBOHttpDocument::getInstance($app)->close(400, 'Missing door access control provider identifier.'); } if (empty($idDevice)) { VBOHttpDocument::getInstance($app)->close(400, 'Missing door access control device identifier.'); } // access the door access factory object $factory = VBOFactory::getDoorAccessControl(); // get the requested integration provider $integration = $factory->getIntegrationProvider($provider); if (!$integration) { VBOHttpDocument::getInstance($app)->close(404, 'Invalid door access control provider identifier.'); } // load the requested integration profile $profile = $factory->loadIntegrationRecord($idProfile); if (!$profile) { VBOHttpDocument::getInstance($app)->close(404, 'Invalid door access control profile identifier.'); } // inject profile record within the integration $integration->setProfileRecord($profile); try { // access the requested device $device = $integration->getDeviceById($idDevice); // access the requested device capability $capability = $device->getCapabilityById($idCapability); } catch (Exception $e) { VBOHttpDocument::getInstance($app)->close($e->getCode() ?: 500, $e->getMessage()); } if ($capability->providesParams() && $noParams && !$capabilitySettings) { // capability provides parameters that require settings for its execution return [ 'capability_params' => VBOParamsRendering::getInstance($capability->getParams(), $retryDataOptions)->setInputName('capability_settings[' . $capability->getID() . ']')->getHtml(), ]; } try { // execute the device capability $capabilityResult = $capability->execute($integration, $device, $capabilitySettings); } catch (Exception $e) { VBOHttpDocument::getInstance($app)->close($e->getCode() ?: 500, $e->getMessage()); } if ($capabilityResult->getOutput()) { // display the capability execution result output (HTML) return [ 'result_html' => (string) $capabilityResult, 'device_updated' => (int) $device->getDataChanged(), ]; } if ($capabilityResult->getText()) { // display the capability execution result text return [ 'result_text' => (string) $capabilityResult, 'device_updated' => (int) $device->getDataChanged(), ]; } // no result information, yet successful return [ 'success' => 1, 'device_updated' => (int) $device->getDataChanged(), ]; } }