From eb7e9ede4ea014c46f2b8a558c5d27cfbc1774fd Mon Sep 17 00:00:00 2001 From: Alex Trofimov Date: Tue, 10 Sep 2024 21:11:05 +0600 Subject: [PATCH 1/3] Upgrade script from 14.0.0-B2 to 14.0.0-RC1 --- .../files/inc/classes/BxDolGrid.php | 17 +- .../files/plugins/autoload.php | 2 +- .../files/plugins/composer/autoload_real.php | 14 +- .../plugins/composer/autoload_static.php | 10 +- .../files/plugins/composer/installed.php | 4 +- .../files/template/scripts/BxBaseGrid.php | 931 ++++++++++++++++++ 6 files changed, 960 insertions(+), 18 deletions(-) create mode 100644 upgrade/files/14.0.0.B2-14.0.0.RC1/files/template/scripts/BxBaseGrid.php diff --git a/upgrade/files/14.0.0.B2-14.0.0.RC1/files/inc/classes/BxDolGrid.php b/upgrade/files/14.0.0.B2-14.0.0.RC1/files/inc/classes/BxDolGrid.php index 58a2946eef..1469804476 100644 --- a/upgrade/files/14.0.0.B2-14.0.0.RC1/files/inc/classes/BxDolGrid.php +++ b/upgrade/files/14.0.0.B2-14.0.0.RC1/files/inc/classes/BxDolGrid.php @@ -383,7 +383,7 @@ protected function _getDataArray ($sFilter, $sOrderField, $sOrderDir, $iStart, $ // sort $sSortField = false; $iSortDir = 1; - if ($sOrderField && !empty($this->_aOptions['sorting_fields']) && is_array($this->_aOptions['sorting_fields']) && in_array($sOrderField, $this->_aOptions['sorting_fields'])) { // explicit order + if ($sOrderField && ($aSortingFields = $this->_getOrderFields()) && in_array($sOrderField, $aSortingFields)) { // explicit order $sSortField = $sOrderField; $iSortDir = 0 === strcasecmp($sOrderDir, 'desc') ? -1 : 1; } elseif (!empty($this->_aOptions['field_order'])) { // order by "order" field @@ -568,11 +568,11 @@ protected function _getDataSqlOrderClause ($sOrderByFilter, $sOrderField, $sOrde { $sOrderClause = ''; - if ($sOrderField && is_array($this->_aOptions['sorting_fields']) && in_array($sOrderField, $this->_aOptions['sorting_fields'])) { // explicit order + if ($sOrderField && ($aSortingFields = $this->_getOrderFields()) && in_array($sOrderField, $aSortingFields)) { // explicit order $sDir = (0 === strcasecmp($sOrderDir, 'desc') ? 'DESC' : 'ASC'); - if (is_array($this->_aOptions['sorting_fields_translatable']) && in_array($sOrderField, $this->_aOptions['sorting_fields_translatable'])) { + if (($aSortingFieldsTranslatable = $this->_getOrderFieldsTranslatable()) && in_array($sOrderField, $aSortingFieldsTranslatable)) { // translatable fields $iLang = BxDolLanguages::getInstance()->getCurrentLangId(); @@ -647,6 +647,17 @@ protected function _getFilterValue() return bx_unicode_urldecode(bx_process_input(bx_get($this->_aOptions['filter_get']))); } + protected function _getOrderFields($bTranslatable = false) + { + $sKey = 'sorting_fields' . ($bTranslatable ? '_translatable' : ''); + return !empty($this->_aOptions[$sKey]) && is_array($this->_aOptions[$sKey]) ? $this->_aOptions[$sKey] : []; + } + + protected function _getOrderFieldsTranslatable() + { + return $this->_getOrderFields(true); + } + protected function _getOrderValue() { return bx_unicode_urldecode(bx_process_input(bx_get($this->_aOptions['order_get_field']))); diff --git a/upgrade/files/14.0.0.B2-14.0.0.RC1/files/plugins/autoload.php b/upgrade/files/14.0.0.B2-14.0.0.RC1/files/plugins/autoload.php index bab64e642c..1e49e4e567 100644 --- a/upgrade/files/14.0.0.B2-14.0.0.RC1/files/plugins/autoload.php +++ b/upgrade/files/14.0.0.B2-14.0.0.RC1/files/plugins/autoload.php @@ -4,4 +4,4 @@ require_once __DIR__ . '/composer/autoload_real.php'; -return ComposerAutoloaderInit03a8066c470486be30535b543d47f96a::getLoader(); +return ComposerAutoloaderInitfd83e10aca1f370f3d7f53da5d1e7afa::getLoader(); diff --git a/upgrade/files/14.0.0.B2-14.0.0.RC1/files/plugins/composer/autoload_real.php b/upgrade/files/14.0.0.B2-14.0.0.RC1/files/plugins/composer/autoload_real.php index 32ca225926..876a8d861f 100644 --- a/upgrade/files/14.0.0.B2-14.0.0.RC1/files/plugins/composer/autoload_real.php +++ b/upgrade/files/14.0.0.B2-14.0.0.RC1/files/plugins/composer/autoload_real.php @@ -2,7 +2,7 @@ // autoload_real.php @generated by Composer -class ComposerAutoloaderInit03a8066c470486be30535b543d47f96a +class ComposerAutoloaderInitfd83e10aca1f370f3d7f53da5d1e7afa { private static $loader; @@ -24,15 +24,15 @@ public static function getLoader() require __DIR__ . '/platform_check.php'; - spl_autoload_register(array('ComposerAutoloaderInit03a8066c470486be30535b543d47f96a', 'loadClassLoader'), true, true); + spl_autoload_register(array('ComposerAutoloaderInitfd83e10aca1f370f3d7f53da5d1e7afa', 'loadClassLoader'), true, true); self::$loader = $loader = new \Composer\Autoload\ClassLoader(\dirname(\dirname(__FILE__))); - spl_autoload_unregister(array('ComposerAutoloaderInit03a8066c470486be30535b543d47f96a', 'loadClassLoader')); + spl_autoload_unregister(array('ComposerAutoloaderInitfd83e10aca1f370f3d7f53da5d1e7afa', 'loadClassLoader')); $useStaticLoader = PHP_VERSION_ID >= 50600 && !defined('HHVM_VERSION') && (!function_exists('zend_loader_file_encoded') || !zend_loader_file_encoded()); if ($useStaticLoader) { require __DIR__ . '/autoload_static.php'; - call_user_func(\Composer\Autoload\ComposerStaticInit03a8066c470486be30535b543d47f96a::getInitializer($loader)); + call_user_func(\Composer\Autoload\ComposerStaticInitfd83e10aca1f370f3d7f53da5d1e7afa::getInitializer($loader)); } else { $map = require __DIR__ . '/autoload_namespaces.php'; foreach ($map as $namespace => $path) { @@ -53,19 +53,19 @@ public static function getLoader() $loader->register(true); if ($useStaticLoader) { - $includeFiles = Composer\Autoload\ComposerStaticInit03a8066c470486be30535b543d47f96a::$files; + $includeFiles = Composer\Autoload\ComposerStaticInitfd83e10aca1f370f3d7f53da5d1e7afa::$files; } else { $includeFiles = require __DIR__ . '/autoload_files.php'; } foreach ($includeFiles as $fileIdentifier => $file) { - composerRequire03a8066c470486be30535b543d47f96a($fileIdentifier, $file); + composerRequirefd83e10aca1f370f3d7f53da5d1e7afa($fileIdentifier, $file); } return $loader; } } -function composerRequire03a8066c470486be30535b543d47f96a($fileIdentifier, $file) +function composerRequirefd83e10aca1f370f3d7f53da5d1e7afa($fileIdentifier, $file) { if (empty($GLOBALS['__composer_autoload_files'][$fileIdentifier])) { require $file; diff --git a/upgrade/files/14.0.0.B2-14.0.0.RC1/files/plugins/composer/autoload_static.php b/upgrade/files/14.0.0.B2-14.0.0.RC1/files/plugins/composer/autoload_static.php index 141228e601..2e6a44846a 100644 --- a/upgrade/files/14.0.0.B2-14.0.0.RC1/files/plugins/composer/autoload_static.php +++ b/upgrade/files/14.0.0.B2-14.0.0.RC1/files/plugins/composer/autoload_static.php @@ -4,7 +4,7 @@ namespace Composer\Autoload; -class ComposerStaticInit03a8066c470486be30535b543d47f96a +class ComposerStaticInitfd83e10aca1f370f3d7f53da5d1e7afa { public static $files = array ( '7b11c4dc42b3b3023073cb14e519683c' => __DIR__ . '/..' . '/ralouphie/getallheaders/src/getallheaders.php', @@ -216,10 +216,10 @@ class ComposerStaticInit03a8066c470486be30535b543d47f96a public static function getInitializer(ClassLoader $loader) { return \Closure::bind(function () use ($loader) { - $loader->prefixLengthsPsr4 = ComposerStaticInit03a8066c470486be30535b543d47f96a::$prefixLengthsPsr4; - $loader->prefixDirsPsr4 = ComposerStaticInit03a8066c470486be30535b543d47f96a::$prefixDirsPsr4; - $loader->prefixesPsr0 = ComposerStaticInit03a8066c470486be30535b543d47f96a::$prefixesPsr0; - $loader->classMap = ComposerStaticInit03a8066c470486be30535b543d47f96a::$classMap; + $loader->prefixLengthsPsr4 = ComposerStaticInitfd83e10aca1f370f3d7f53da5d1e7afa::$prefixLengthsPsr4; + $loader->prefixDirsPsr4 = ComposerStaticInitfd83e10aca1f370f3d7f53da5d1e7afa::$prefixDirsPsr4; + $loader->prefixesPsr0 = ComposerStaticInitfd83e10aca1f370f3d7f53da5d1e7afa::$prefixesPsr0; + $loader->classMap = ComposerStaticInitfd83e10aca1f370f3d7f53da5d1e7afa::$classMap; }, null, ClassLoader::class); } diff --git a/upgrade/files/14.0.0.B2-14.0.0.RC1/files/plugins/composer/installed.php b/upgrade/files/14.0.0.B2-14.0.0.RC1/files/plugins/composer/installed.php index e7a7784af8..d50a9c42ab 100644 --- a/upgrade/files/14.0.0.B2-14.0.0.RC1/files/plugins/composer/installed.php +++ b/upgrade/files/14.0.0.B2-14.0.0.RC1/files/plugins/composer/installed.php @@ -5,7 +5,7 @@ 'type' => 'library', 'install_path' => __DIR__ . '/../../', 'aliases' => array(), - 'reference' => '53588980042992e9da0cf02b65071d4a81815440', + 'reference' => '53576e1540d7625f6f9bed8ee0f17a99467d2870', 'name' => 'unaio/una', 'dev' => true, ), @@ -359,7 +359,7 @@ 'type' => 'library', 'install_path' => __DIR__ . '/../../', 'aliases' => array(), - 'reference' => '53588980042992e9da0cf02b65071d4a81815440', + 'reference' => '53576e1540d7625f6f9bed8ee0f17a99467d2870', 'dev_requirement' => false, ), 'wikimedia/less.php' => array( diff --git a/upgrade/files/14.0.0.B2-14.0.0.RC1/files/template/scripts/BxBaseGrid.php b/upgrade/files/14.0.0.B2-14.0.0.RC1/files/template/scripts/BxBaseGrid.php new file mode 100644 index 0000000000..d109fe4727 --- /dev/null +++ b/upgrade/files/14.0.0.B2-14.0.0.RC1/files/template/scripts/BxBaseGrid.php @@ -0,0 +1,931 @@ +_oTemplate = $oTemplate; + else + $this->_oTemplate = BxDolTemplate::getInstance(); + + $this->_aPopupOptions = []; + + $this->_aQueryAppend = [ + $this->_oTemplate->getCodeKey() => $this->_oTemplate->getCode() + ]; + $this->_aQueryAppendExclude = []; + $this->_aQueryAppendExcludeApi = [$this->_oTemplate->getCodeKey()]; + + $this->_aQueryReset = [ + $this->_aOptions['filter_get'], + $this->_aOptions['order_get_field'], + $this->_aOptions['order_get_dir'], + $this->_aOptions['paginate_get_start'], + $this->_aOptions['paginate_get_per_page'] + ]; + + $this->_aConfirmMessages = []; + } + + public function performActionDisplay() + { + if($this->_bIsApi) + return $this->getCodeAPI(); + + require_once(BX_DIRECTORY_PATH_INC . "design.inc.php"); + + echoJson(array( + 'grid' => $this->getCode(false), + 'total_count' => $this->_iTotalCount, + 'total_count_f' => $this->_getCounter() + )); + } + + public function performActionReorder() + { + $this->_replaceMarkers (); + + $aOrder = bx_get($this->_sObject . '_row'); + $iOrder = 0; + foreach ($aOrder as $mixedId) + $this->_updateOrder($mixedId, ++$iOrder); + + echoJson(array()); + } + + public function performActionDelete() + { + $this->_replaceMarkers (); + + $aResult = []; + $iAffected = 0; + $aIds = bx_get('ids'); + if (!$aIds || !is_array($aIds)) + return $this->_getActionResult($aResult); + + foreach ($aIds as $mixedId) + $iAffected += $this->_delete($mixedId) ? 1 : 0; + + if($iAffected) + $aResult = !$this->_bIsApi ? ['grid' => $this->getCode(false)] : []; + else + $aResult = ['msg' => _t("_sys_grid_delete_failed")]; + + return $this->_getActionResult($aResult); + } + + public function performActionEnable($mixedChecked = null) + { + $this->_replaceMarkers (); + + $aIds = bx_get('ids'); + if (!$aIds || !is_array($aIds)) { + echoJson(array()); + exit; + } + + $iChecked = (int)($mixedChecked !== null ? $mixedChecked : bx_get('checked')); + + $aAffectedIds = array (); + foreach ($aIds as $mixedId) + if ($this->_enable($mixedId, $iChecked)) + $aAffectedIds[] = preg_match("/^[\d\w]+$/", $mixedId) ? $mixedId : (int)$mixedId; + + $sAction = $iChecked ? 'enable' : 'disable'; + + if($this->_bIsApi) + return $aAffectedIds; + + echo echoJson(array($sAction => $aAffectedIds)); + } + + public function getCode ($isDisplayHeader = true) + { + $this->_replaceMarkers (); + + if ($isDisplayHeader && empty($this->_aOptions['paginate_url'])) { + // reset page query params if grid is just initialized and it uses AJAX paginate + $this->resetQueryParams(); + } + + $sPaginate = ''; + $aData = array(); + + $sIdWrapper = 'bx-grid-wrap-' . $this->_sObject; + $sIdContainer = 'bx-grid-cont-' . $this->_sObject; + $sIdTable = 'bx-grid-table-' . $this->_sObject; + + $sFilter = $this->_getFilterValue(); + $sOrderField = $this->_getOrderValue(); + $sOrderDir = 0 === strcasecmp('desc', bx_get($this->_aOptions['order_get_dir'])) ? 'DESC' : 'ASC'; + + $iStart = 0; + if($this->_aOptions['paginate_get_start'] && ($iStartGet = (int)bx_get($this->_aOptions['paginate_get_start'])) >= 0) + $iStart = $iStartGet; + + $iPerPage = 10; + if($this->_aOptions['paginate_get_per_page'] && ($iPerPageGet = (int)bx_get($this->_aOptions['paginate_get_per_page'])) > 0) + $iPerPage = $iPerPageGet; + else if($this->_aOptions['paginate_per_page']) + $iPerPage = (int)$this->_aOptions['paginate_per_page']; + + if ($this->_aOptions['paginate_get_start']) { + + $aData = $this->_getData ($sFilter, $sOrderField, $sOrderDir, $iStart, $iPerPage + 1); + + $sPageUrl = false; + if (!empty($this->_aOptions['paginate_url'])) { + + $sPageUrl = $this->_aOptions['paginate_url']; + + $aParamsAppend = array(); + if ($sFilter) { + $aParamsAppend['filter'] = bx_process_input(bx_get($this->_aOptions['filter_get'])); + } + if ($sOrderField) { + $aParamsAppend['order_field'] = bx_process_input(bx_get($this->_aOptions['order_get_field'])); + $aParamsAppend['order_dir'] = bx_process_input(bx_get($this->_aOptions['order_get_dir'])); + } + if ($aParamsAppend) + $sPageUrl = bx_append_url_params($sPageUrl, $aParamsAppend); + } + + $aPaginateParams = array( + 'start' => $iStart, + 'per_page' => $iPerPage, + 'page_url' => $sPageUrl ? $sPageUrl : "javascript:glGrids." . $this->_sObject . ".reload('{start}'); void(0);", + ); + + $oPaginate = new BxTemplPaginate($aPaginateParams, $this->_oTemplate); + $oPaginate->setNumFromDataArray($aData); + + if (isset($this->_aOptions['paginate_simple']) && false !== $this->_aOptions['paginate_simple']) + $sPaginate = $oPaginate->getSimplePaginate($this->_aOptions['paginate_simple']); + else + $sPaginate = $oPaginate->getPaginate(); + } else { + $aData = $this->_getData ($sFilter, $sOrderField, $sOrderDir, $iStart, $iPerPage); + } + + if((empty($aData) || !is_array($aData)) && isset($this->_aBrowseParams['empty_message']) && !(bool)$this->_aBrowseParams['empty_message']) + return ''; + + $sPopupOptions = '{}'; + if (!empty($this->_aPopupOptions) && is_array($this->_aPopupOptions)) + $sPopupOptions = json_encode($this->_aPopupOptions); + + $aQueryAppend = array_merge(is_array($this->_aQueryAppend) ? $this->_aQueryAppend : array(), is_array($this->_aMarkers) ? $this->_aMarkers : array()); + if(!empty($this->_aQueryAppendExclude) && is_array($this->_aQueryAppendExclude)) + $aQueryAppend = array_diff_key($aQueryAppend, array_flip($this->_aQueryAppendExclude)); + + $sQueryAppend = '{}'; + if (!empty($aQueryAppend) && is_array($aQueryAppend)) + $sQueryAppend = json_encode($aQueryAppend); + + $sConfirmMessages = '{}'; + if (!empty($this->_aConfirmMessages) && is_array($this->_aConfirmMessages)) + $sConfirmMessages = json_encode($this->_aConfirmMessages); + + $iColumns = count($this->_aOptions['fields']); + $aVarsHead = $this->_getRowHead(); + + $sClassHeader = ''; + if($this->_aOptions['show_total_count'] == 0) + $sClassHeader .= ' bx-gh-no-counter'; + + $aVars = array ( + 'object' => $this->_sObject, + 'csrf_token' => BxDolForm::getCsrfToken(), + 'id_table' => $sIdTable, + 'id_cont' => $sIdContainer, + 'id_wrap' => $sIdWrapper, + 'class_table_wrapper' => $this->_aOptions['responsive'] ? 'bx-grid-table-wrapper-responsive' : '', + 'sortable' => empty($this->_aOptions['field_order']) ? 0 : 1, + 'sorting' => empty($this->_getOrderFields()) ? 0 : 1, + 'sorting_field' => $sOrderField, + 'sorting_dir' => $sOrderDir, + 'bx_if:display_head' => array( + 'condition' => !empty($aVarsHead), + 'content' => array( + 'bx_repeat:row_header' => $aVarsHead, + 'columns' => $iColumns, + ) + ), + 'bx_repeat:rows_data' => $this->_getRowsDataDesign ($aData), + 'paginate_get_start' => $this->_aOptions['paginate_get_start'], + 'paginate_get_per_page' => $this->_aOptions['paginate_get_per_page'], + 'start' => $iStart, + 'per_page' => $iPerPage, + 'filter' => bx_js_string($sFilter, BX_ESCAPE_STR_APOS), + 'filter_get' => bx_js_string($this->_aOptions['filter_get']), + 'order_field' => bx_js_string($sOrderField, BX_ESCAPE_STR_APOS), + 'order_dir' => bx_js_string($sOrderDir, BX_ESCAPE_STR_APOS), + 'order_get_field' => bx_js_string($this->_aOptions['order_get_field']), + 'order_get_dir' => bx_js_string($this->_aOptions['order_get_dir']), + 'popup_options' => $sPopupOptions, + 'query_append' => $sQueryAppend, + 'confirm_messages' => $sConfirmMessages, + 'columns' => $iColumns, + 'bx_if:display_footer' => array( + 'condition' => !empty($this->_aOptions['actions_bulk']) || !empty($sPaginate), + 'content' => array( + 'bx_if:actions_bulk' => array ( + 'condition' => !empty($this->_aOptions['actions_bulk']), + 'content' => array( + 'actions_bulk' => $this->_getActions ('bulk'), + ), + ), + 'paginate' => $sPaginate, + ) + ), + 'bx_if:display_header' => array ( + 'condition' => $isDisplayHeader, + 'content' => array ( + 'class' => $sClassHeader, + 'bx_if:actions_independent' => array ( + 'condition' => !empty($this->_aOptions['actions_independent']), + 'content' => array( + 'actions_independent' => $this->_getActions ('independent'), + ), + ), + 'bx_if:filter' => array ( + 'condition' => !empty($this->_aOptions['filter_fields']) || !empty($this->_aOptions['filter_fields_translatable']), + 'content' => array( + 'controls' => $this->_getFilterControls(), + ), + ), + 'bx_if:counter' => array ( + 'condition' => $this->_aOptions['show_total_count'] == 1, + 'content' => array( + 'counter' => $this->_getCounter(), + ), + ), + ), + ), + ); + + $this->_addJsCss(); + + return $this->_oTemplate->parseHtmlByName('grid.html', $aVars); + } + + /** + * Get grid code API. + * @return array + */ + public function getCodeAPI($bForceReturn = false) + { + $this->_replaceMarkers(); + + $sFilter = bx_unicode_urldecode(bx_process_input(bx_get($this->_aOptions['filter_get']))); + $sOrderField = bx_unicode_urldecode(bx_process_input(bx_get($this->_aOptions['order_get_field']))); + $sOrderDir = 0 === strcasecmp('desc', bx_get($this->_aOptions['order_get_dir'])) ? 'DESC' : 'ASC'; + + $iStart = 0; + if($this->_aOptions['paginate_get_start'] && ($iStartGet = (int)bx_get($this->_aOptions['paginate_get_start'])) >= 0) + $iStart = $iStartGet; + + $iPerPage = 10; + if($this->_aOptions['paginate_get_per_page'] && ($iPerPageGet = (int)bx_get($this->_aOptions['paginate_get_per_page'])) > 0) + $iPerPage = $iPerPageGet; + else if($this->_aOptions['paginate_per_page']) + $iPerPage = (int)$this->_aOptions['paginate_per_page']; + + $aData = $this->_getData($sFilter, $sOrderField, $sOrderDir, $iStart, $iPerPage); + if(!empty($aData) && is_array($aData)) + $aData = $this->decodeDataAPI($aData); + + $aQueryAppend = []; + if(!empty($this->_aQueryAppend) && is_array($this->_aQueryAppend)) + $aQueryAppend = array_merge($aQueryAppend, $this->_aQueryAppend); + if(!empty($this->_aMarkers) && is_array($this->_aMarkers)) + $aQueryAppend = array_merge($aQueryAppend, $this->_aMarkers); + if(!empty($this->_aQueryAppendExclude) && is_array($this->_aQueryAppendExclude)) + $aQueryAppend = array_diff_key($aQueryAppend, array_flip($this->_aQueryAppendExclude)); + if(!empty($this->_aQueryAppendExcludeApi) && is_array($this->_aQueryAppendExcludeApi)) + $aQueryAppend = array_diff_key($aQueryAppend, array_flip($this->_aQueryAppendExcludeApi)); + + return [ + 'settings' => [ + 'object' => $this->_aOptions['object'], + 'field_id' => $this->_aOptions['field_id'], + 'start' => $iStart, + 'per_page' => $iPerPage, + 'filters' => $this->_getFilterControlsAPI(), + 'query_append' => $aQueryAppend + ], + 'header' => $this->_getRowHeadAPI(), + 'data' => defined('BX_API_PAGE') && !$bForceReturn ? [] : $aData, + 'actions' => [ + 'independent' => $this->_getActionsAPI('independent'), + 'bulk' => $this->_getActionsAPI('bulk') + ] + ]; + } + + public function decodeDataAPI($aData) + { + $sKeyId = $this->_aOptions['field_id']; + $sMethodDefault = '_getCellDefault'; + + $aDataRv = []; + foreach($aData as $iKey => $aRow) { + $aDataRv[$iKey] = [$sKeyId => $aData[$iKey][$sKeyId]]; + + foreach($this->_aOptions['fields'] as $sKey => $aField) { + $sMethod = '_getCell' . $this->_genMethodName($sKey); + if(!method_exists($this, $sMethod)) + $sMethod = $sMethodDefault; + + $aDataRv[$iKey][$sKey] = $this->$sMethod(isset($aData[$iKey][$sKey]) ? $aData[$iKey][$sKey] : _t('_undefined'), $sKey, $aField, $aRow); + } + } + + return $aDataRv; + } + + public function getFormBlockAPI($oForm, $sAction, $iId = 0) + { + return [ + bx_api_get_block('form', $oForm->getCodeAPI(), [ + 'ext' => [ + 'name' => $this->_oModule->getName(), + 'title' => $this->getFormBlockTitleAPI($sAction, $iId), + 'request' => ['url' => $this->getFormCallBackUrlAPI($sAction, $iId), 'immutable' => true]] + ] + ) + ]; + } + + public function getFormBlockTitleAPI($sAction, $iId) + { + return ''; + } + + public function getFormCallBackUrlAPI($sAction, $iId) + { + return ''; + } + + /** + * Reset query params, like filter and page number + */ + public function resetQueryParams() + { + foreach ($this->_aQueryReset as $sKey) { + unset($_GET[$sKey]); + unset($_POST[$sKey]); + } + } + + protected function _getRowHead() + { + $aRet = array(); + foreach ($this->_aOptions['fields'] as $sKey => $a) { + + $sMethod = '_getCellHeaderDefault'; + $sCustomMethod = '_getCellHeader' . $this->_genMethodName($sKey); + if (method_exists($this, $sCustomMethod)) + $sMethod = $sCustomMethod; + + $aRet[] = array('header_cell' => $this->$sMethod($sKey, $a)); + } + return $aRet; + } + + protected function _getRowHeadAPI() + { + $aHeader = []; + + foreach($this->_aOptions['fields'] as $sKey => $aField) { + $sMethod = '_getCellHeader' . $this->_genMethodName($sKey); + if(method_exists($this, $sMethod)) + $aHeader[] = $this->$sMethod($sKey, $aField); + else + $aHeader[] = [ + 'name' => bx_process_output($aField['name']), + 'title' => bx_process_output($aField['title']), + 'width' => $aField['width'] + ]; + } + + return $aHeader; + } + + protected function _getCellHeaderDefault ($sKey, $aField) + { + $sHeader = bx_process_output($aField['title']); + + if (($aSortingFields = $this->_getOrderFields()) && in_array($sKey, $aSortingFields)) { + $sHeader = '' . $sHeader . ''; + $aField['attr_head']['bx_grid_sort_head'] = $sKey; + } + + $sAttr = $this->_convertAttrs( + $aField, 'attr_head', + 'bx-def-padding-sec-bottom bx-def-padding-sec-top bx-grid-header-' . $sKey, // add default classes + isset($aField['width']) ? 'width:' . $aField['width'] : false // add default styles + ); + + return $this->_getCellHeaderWrapper ($sKey, $aField, $sHeader, $sAttr); + } + + protected function _getCellHeaderCheckbox ($sKey, $aField) + { + if($this->_bIsApi){ + return [ + 'name' => bx_process_output($aField['name']), + 'title' => bx_process_output($aField['title']), + 'width' => $aField['width'] + ]; + } + + $aAttr = array( + 'type' => 'checkbox', + 'id' => $this->_sObject . '_check_all', + 'name' => $this->_sObject . '_check_all', + 'onclick' => "$('input[name=" . $this->_sObject . "_check]:not([disabled])').attr('checked', this.checked)" + ); + if($this->_bSelectAll) + $aAttr['checked'] = 'checked'; + + $aField['attr'] = isset($aField['attr']) && is_array($aField['attr']) ? array_merge($aAttr, $aField['attr']) : $aAttr; + + $sAttrHead = $this->_convertAttrs( + $aField, 'attr_head', + 'bx-def-padding-sec-bottom bx-def-padding-sec-top bx-grid-header-' . $sKey, // add default classes + isset($aField['width']) ? 'width:' . $aField['width'] : false // add default styles + ); + return $this->_getCellHeaderWrapper ($sKey, $aField, ' _convertAttrs($aField, 'attr') . ' /> ', $sAttrHead); + } + + protected function _getCellHeaderWrapper ($sKey, $aField, $sHeader, $sAttr) + { + return '' . $sHeader . ''; + } + + /** + * Check if the whole row is disabled. + * When row is disabled - checkbox is not selectable, actions aren't clickable and text is grayed out. + * By default all rows aren't disabled. + * @param $aRow row array + * @return boolean + */ + protected function _isRowDisabled($aRow) + { + if (isset($aRow[$this->_aOptions['field_active']]) && !$this->_switcherState2Checked($aRow[$this->_aOptions['field_active']])) + return true; + return false; + } + + /** + * Determine how actions are disabled when whole row is disabled. + * @param $aRow row array + * @return null - disable/enable actions when row is disabled/enabled, true - actions are always disabled, false - actions are always enabled + */ + protected function _getActionsDisabledBehavior($aRow) + { + return null; + } + + /** + * Check if the checkbox is disabled. + * @param $aRow row array + * @return boolean + */ + protected function _isCheckboxDisabled($aRow) + { + return $this->_isRowDisabled($aRow); + } + + /** + * Is checkbox checked by default ? + * By default no one checkbox is selected. + * @return boolean + */ + protected function _isCheckboxSelected($mixedValue, $sKey, $aField, $aRow) + { + return $this->_bSelectAll; + } + + /** + * Is switcher on by default ? + * By default no one switcher is on. + * @return boolean + */ + protected function _isSwitcherOn($mixedValue, $sKey, $aField, $aRow) + { + return $this->_switcherState2Checked($mixedValue); + } + + /** + * Convert switcher checked status to the actual value ? + * @return boolean + */ + protected function _switcherChecked2State($isChecked) + { + return $isChecked ? 1 : 0; + } + + /** + * Convert switcher value to checked(boolean) value ? + * @return boolean + */ + protected function _switcherState2Checked($mixedState) + { + return $mixedState ? true : false; + } + + protected function _getRowsDataDesign (&$aData) + { + $aGrid = array(); + + if(empty($aData)) + $aGrid[] = array( + 'id_row' => 0, + 'row_class' => 'bx-grid-table-row-empty', + 'row' => '' . MsgBox(_t('_Empty')) . '' + ); + else + foreach ($aData as $aRow) + $aGrid[] = array( + 'id_row' => $this->_getRowId($aRow), + 'row_class' => $this->_isRowDisabled($aRow) ? 'bx-grid-table-row-disabled bx-def-font-grayed' : '', + 'row' => $this->_getRowDesign($aRow) + ); + + return $aGrid; + } + + protected function _getRowId($mixedRow) + { + if(is_string($mixedRow)) + $sId = rand(1, getrandmax()); + else + $sId = $mixedRow[$this->_aOptions['field_id']]; + + return $this->_sObject . '_row_' . $sId; + } + + protected function _getRowDesign($mixedRow) + { + $sRow = ''; + if(is_string($mixedRow)) + $sRow = '' . $mixedRow . ''; + else + foreach($this->_aOptions['fields'] as $sKey => $aField) + $sRow .= $this->_getCellDesign($sKey, $aField, $mixedRow); + + return $sRow; + } + + protected function _getCellDesign($sKey, $aField, $aRow) + { + $sMethod = '_getCellDefault'; + if ($this->_aOptions['field_order'] == $sKey) + $sMethod = '_getCellOrder'; + + $sCustomMethod = '_getCell' . $this->_genMethodName($sKey); + if (method_exists($this, $sCustomMethod)) + $sMethod = $sCustomMethod; + + $mixedValue = $this->_getCellData($sKey, $aField, $aRow); + + if ($aField['translatable']) + $mixedValue = _t($mixedValue); + + $mixedValue = $this->_limitMaxLength($mixedValue, $sKey, $aField, $aRow, $this->_isDisplayPopupOnTextOverflow); + + return $this->$sMethod($mixedValue, $sKey, $aField, $aRow); + } + + protected function _getCellCheckbox ($mixedValue, $sKey, $aField, $aRow) + { + if($this->_bIsApi) + return ['type' => 'checkbox', 'data' => $aRow[$this->_aOptions['field_id']]]; + + $sAttr = $this->_convertAttrs( + $aField, 'attr_cell', + 'bx-def-padding-sec-bottom bx-def-padding-sec-top', // add default classes + isset($aField['width']) ? 'width:' . $aField['width'] : false // add default styles + ); + $sDisabled = ($this->_isCheckboxDisabled($aRow) ? 'disabled="disabled"' : ''); + $sSelected = ($this->_isCheckboxSelected($mixedValue, $sKey, $aField, $aRow) ? 'checked="checked"' : ''); + $sVal = $aRow[$this->_aOptions['field_id']]; + return ''; + } + + protected function _getCellSwitcher ($mixedValue, $sKey, $aField, $aRow) + { + if($this->_bIsApi) + return ['type' => 'switcher', 'data' => $aRow[$this->_aOptions['field_active']], 'fld' => $this->_aOptions['field_active']]; + + $sAttr = $this->_convertAttrs( + $aField, 'attr_cell', + 'bx-def-padding-sec-bottom bx-def-padding-sec-top', // add default classes + isset($aField['width']) ? 'width:' . $aField['width'] : false // add default styles + ); + + $oForm = new BxTemplFormView(array(), $this->_oTemplate); + $oForm->addCssJs(); + $aInput = array( + 'type' => 'switcher', + 'name' => $this->_sObject . '_switch_' . $aRow[$this->_aOptions['field_id']], + 'caption' => '', + 'attrs' => array ( + 'bx_grid_action_single' => 'enable', + 'bx_grid_action_confirm' => '', + 'bx_grid_action_data' => $aRow[$this->_aOptions['field_id']], + ), + 'value' => $aRow[$this->_aOptions['field_id']], + 'checked' => $this->_isSwitcherOn(isset($aRow[$this->_aOptions['field_active']]) ? $aRow[$this->_aOptions['field_active']] : false, $sKey, $aField, $aRow), + ); + $sSwitcher = $oForm->genInput($aInput); + return '' . $sSwitcher . ''; + } + + protected function _getCellOrder ($mixedValue, $sKey, $aField, $aRow) + { + if($this->_bIsApi) + return ['type' => 'order', 'data'=> $mixedValue]; + + $sAttr = $this->_convertAttrs( + $aField, 'attr_cell', + 'bx-def-padding-sec-bottom bx-def-padding-sec-top', // add default classes + isset($aField['width']) ? 'width:' . $aField['width'] : false // add default styles + ); + + return '
'; + } + + protected function _getCellActions ($mixedValue, $sKey, $aField, $aRow) + { + $sAttr = $this->_convertAttrs( + $aField, 'attr_cell', + 'bx-def-padding-sec-bottom bx-def-padding-sec-top', // add default classes + isset($aField['width']) ? 'width:' . $aField['width'] : false // add default styles + ); + + $mixedDisabledBehavior = $this->_getActionsDisabledBehavior($aRow); + $mixedActions = $this->_getActions('single', $aRow[$this->_aOptions['field_id']], false, null === $mixedDisabledBehavior ? $this->_isRowDisabled($aRow) : $mixedDisabledBehavior, null !== $mixedDisabledBehavior, $aRow); + + if($this->_bIsApi) + return ['type' => 'actions', 'data' => $mixedActions]; + + return '
' . $mixedActions . '
'; + } + + protected function _getCellDefault ($mixedValue, $sKey, $aField, $aRow) + { + if($this->_bIsApi) + return ['type' => 'text', 'value'=> (int)$aField['translatable'] ? _t($mixedValue) : $mixedValue]; + + $sAttr = $this->_convertAttrs( + $aField, 'attr_cell', + 'bx-def-padding-sec-bottom bx-def-padding-sec-top', // add default classes + isset($aField['width']) ? 'width:' . $aField['width'] : false // add default styles + ); + return '' . $mixedValue . ''; + } + + protected function _getActions ($sType, $sActionData = false, $isSmall = false, $isDisabled = false, $isPermanentState = false, $aRow = array()) + { + $sActionsType = 'actions_' . $sType; + if (empty($this->_aOptions[$sActionsType]) || !is_array($this->_aOptions[$sActionsType])) + return ''; + + $mixedResult = $this->_bIsApi ? [] : ''; + foreach ($this->_aOptions[$sActionsType] as $sKey => $a) { + if(!$a['active'] || (!$a['title'] && !$a['icon'])) + continue; + + $sFunc = '_getAction' . $this->_genMethodName($sKey); + if (!method_exists($this, $sFunc)) + $sFunc = empty($a) ? '_getActionDivider' : '_getActionDefault'; + + if (!isset($a['attr']['bx_grid_action'])) { + $a['attr']['bx_grid_action_' . $sType] = $sKey; + if (!empty($sActionData)) + $a['attr']['bx_grid_action_data'] = $sActionData; + if (isset($a['confirm'])) + $a['attr']['bx_grid_action_confirm'] = $a['confirm'] ? 1 : 0; + $a['attr']['bx_grid_action_reset_paginate'] = false === strpos($sKey, 'delete') ? 0 : 1; // reset paginate after deleting row + } + + if ($isPermanentState && !isset($a['attr']['bx_grid_permanent_state'])) + $a['attr']['bx_grid_permanent_state'] = 1; + + if ($this->_bIsApi) + $mixedResult[] = $this->$sFunc($sType, $sKey, $a, $isSmall, $isDisabled, $aRow); + else + $mixedResult .= $this->$sFunc($sType, $sKey, $a, $isSmall, $isDisabled, $aRow); + } + + return $mixedResult; + } + + protected function _getActionsAPI ($sType) + { + $sActionsType = 'actions_' . $sType; + if(empty($this->_aOptions[$sActionsType]) || !is_array($this->_aOptions[$sActionsType])) + return []; + + + + foreach ($this->_aOptions[$sActionsType] as $sKey => $aAction){ + $sFunc = '_getAction' . $this->_genMethodName($sType . '_' . $sKey); + if (method_exists($this, $sFunc)){ + $this->_aOptions[$sActionsType][$sKey] = $this->$sFunc($aAction); + } + else{ + $this->_aOptions[$sActionsType][$sKey]['type'] = 'modal'; + $this->_aOptions[$sActionsType][$sKey]['action'] = $sKey; + $this->_aOptions[$sActionsType][$sKey]['params'] = ''; + } + } + return $this->_aOptions[$sActionsType]; + } + + protected function _getActionDelete($sType, $sKey, $a, $isSmall = false, $isDisabled = false, $aRow = array()) + { + if($this->_bIsApi) + return array_merge($a, ['name' => $sKey, 'type' => 'callback', 'on_callback' => 'hide_row']); + + return $this->_getActionDefault($sType, $sKey, $a, $isSmall, $isDisabled, $aRow); + } + + protected function _getActionDefault ($sType, $sKey, $a, $isSmall = false, $isDisabled = false, $aRow = array()) + { + + if ($a['icon_only'] && empty($a['attr']['title']) && !empty($a['title'])) + $a['attr']['title'] = $a['title']; + + if ($this->_bIsApi) { + $sFunc = '_getAction' . $this->_genMethodName($sType . '_' . $sKey); + if (method_exists($this, $sFunc)) { + $aAction = $this->$sFunc($a, ['id'=> $aRow[$this->_aOptions['field_id']]]); + if(empty($aAction) || !is_array($aAction)) + return []; + + return array_merge($a, ['name' => $sKey], $aAction); + } + else { + return array_merge($a, ['name' => $sKey, 'type' => 'modal', 'action' => $sKey, 'params' => '&id=' . $aRow[$this->_aOptions['field_id']] ]); + } + + } + + $sAttr = $this->_convertAttrs( + $a, 'attr', + 'bx-btn bx-def-margin-thd' . ($isSmall ? ' bx-btn-small' : '') . ($isDisabled ? ' bx-btn-disabled' : '') // add default classes + ); + + $sIcon = ''; + $sImage = ''; + if (!empty($a['icon'])) { + if (false === strpos($a['icon'], '.')) + $sIcon = ''; + elseif ($sIconUrl = $this->_oTemplate->getIconUrl($a['icon'])) + $sImage = ''; + } + + return ''; + } + + protected function _getActionDivider ($sType, $sKey, $a, $isSmall = false, $isDisabled = false, $aRow = array()) + { + return '
|
'; + } + + protected function _getActionResult($aResult) + { + return $this->_bIsApi ? $aResult : echoJson($aResult); + } + + protected function _getFilterControls () + { + $oForm = new BxTemplFormView(array()); + + $aInput = array( + 'type' => 'text', + 'name' => 'keyword', + 'attrs' => array( + 'id' => 'bx-grid-search-' . $this->_sObject + ) + ); + + $this->_oTemplate->addCss('forms.css'); + return $oForm->genRow($aInput); + } + + protected function _getFilterControlsAPI($aFilters = []) + { + if(!empty($this->_aOptions['filter_fields']) || !empty($this->_aOptions['filter_fields_translatable'])) + $aFilters['search'] = []; + + return $aFilters; + } + + protected function _getCounter() + { + return _t('_sys_grid_total_count', $this->_iTotalCount); + } + + protected function _limitMaxLength ($mixedValue, $sKey, $aField, $aRow, $isDisplayPopupOnTextOverflow, $bReturnString = true) + { + if ($aField['chars_limit'] > 0) + $mixedValue = BxTemplFunctions::getInstance()->getStringWithLimitedLength($mixedValue, $aField['chars_limit'], $isDisplayPopupOnTextOverflow, $bReturnString); + return $mixedValue; + } + + protected function _convertAttrs ($aField, $sAttrName, $sClasses = false, $sStyles = false) + { + if (!empty($aField['hidden_on'])) { + $aHiddenOn = array( + pow(2, BX_DB_HIDDEN_PHONE - 1) => 'bx-def-media-phone-hide', + pow(2, BX_DB_HIDDEN_TABLET - 1) => 'bx-def-media-tablet-hide', + pow(2, BX_DB_HIDDEN_DESKTOP - 1) => 'bx-def-media-desktop-hide', + pow(2, BX_DB_HIDDEN_MOBILE - 1) => 'bx-def-mobile-app-hide' + ); + foreach ($aHiddenOn as $iHiddenOn => $sClass) + if ((int)$aField['hidden_on'] & $iHiddenOn) + $sClasses .= ' ' . $sClass; + } + + return bx_convert_array2attrs( + isset($aField[$sAttrName]) && is_array($aField[$sAttrName]) ? $aField[$sAttrName] : array(), + $sClasses, + $sStyles + ); + } + + protected function _updateOrder($mixedId, $iOrder) + { + $oDb = BxDolDb::getInstance(); + $sTable = $this->_aOptions['table']; + $sFieldId = $this->_aOptions['field_id']; + $sFieldOrder = $this->_aOptions['field_order']; + $sQuery = $oDb->prepare("UPDATE `{$sTable}` SET `{$sFieldOrder}` = ? WHERE `{$sFieldId}` = ?", $iOrder, $mixedId); + return $oDb->query($sQuery); + } + + protected function _delete ($mixedId) + { + $oDb = BxDolDb::getInstance(); + $sTable = $this->_aOptions['table']; + $sFieldId = $this->_aOptions['field_id']; + $sQuery = $oDb->prepare("DELETE FROM `{$sTable}` WHERE `{$sFieldId}` = ?", $mixedId); + return $oDb->query($sQuery); + } + + protected function _enable ($mixedId, $isChecked) + { + $oDb = BxDolDb::getInstance(); + $sTable = $this->_aOptions['table']; + $sFieldId = $this->_aOptions['field_id']; + $sFieldActive = $this->_aOptions['field_active']; + $sQuery = $oDb->prepare("UPDATE `{$sTable}` SET `$sFieldActive` = ? WHERE `{$sFieldId}` = ?", $this->_switcherChecked2State($isChecked), $mixedId); + return $oDb->query($sQuery); + } + + protected function _addJsCss() + { + if ($this->_aOptions['field_order']) { + $this->_oTemplate->addJs(array( + 'jquery-ui/jquery-ui.custom.min.js', + 'URI.min.js', + )); + } + + $this->_oTemplate->addJs('BxDolGrid.js'); + $this->_oTemplate->addCss('grid.css'); + + $this->_oTemplate->addJsTranslation('_sys_grid_confirmation'); + } +} + +/** @} */ From eede63a7e545b4a77d0e4da3e3a969731aea045d Mon Sep 17 00:00:00 2001 From: Alex Trofimov Date: Tue, 10 Sep 2024 21:37:23 +0600 Subject: [PATCH 2/3] Upgrade script from 14.0.0-B2 to 14.0.0-RC1 --- upgrade/files/14.0.0.B2-14.0.0.RC1/check.php | 11 ++++++++--- 1 file changed, 8 insertions(+), 3 deletions(-) diff --git a/upgrade/files/14.0.0.B2-14.0.0.RC1/check.php b/upgrade/files/14.0.0.B2-14.0.0.RC1/check.php index e298fd672f..3a4e885bc6 100644 --- a/upgrade/files/14.0.0.B2-14.0.0.RC1/check.php +++ b/upgrade/files/14.0.0.B2-14.0.0.RC1/check.php @@ -2,8 +2,13 @@ $mixCheckResult = 'Update can not be applied'; -$sVer = $this->oDb->getOne("SELECT `version` FROM `sys_modules` WHERE `name` = 'system'"); -if ('14.0.0.B2' == $sVer || '14.0.0-B2' == $sVer) - $mixCheckResult = true; +if (!(PHP_VERSION_ID >= 80100)) { + $mixCheckResult = 'This update requires a PHP version ">= 8.1.0". You are running ' . PHP_VERSION; +} +else { + $sVer = $this->oDb->getOne("SELECT `version` FROM `sys_modules` WHERE `name` = 'system'"); + if ('14.0.0.B2' == $sVer || '14.0.0-B2' == $sVer) + $mixCheckResult = true; +} return $mixCheckResult; From c2fab91ce3d53ba348610f7e6fae14a8c0623af0 Mon Sep 17 00:00:00 2001 From: Alex Trofimov Date: Wed, 11 Sep 2024 12:57:42 +0600 Subject: [PATCH 3/3] Upgrade script from 14.0.0-B2 to 14.0.0-RC1 --- .../files/14.0.0.B2-14.0.0.RC1/files_delete.php | 16 +++++++++++++++- 1 file changed, 15 insertions(+), 1 deletion(-) diff --git a/upgrade/files/14.0.0.B2-14.0.0.RC1/files_delete.php b/upgrade/files/14.0.0.B2-14.0.0.RC1/files_delete.php index e2a977c787..09da29ef5e 100644 --- a/upgrade/files/14.0.0.B2-14.0.0.RC1/files_delete.php +++ b/upgrade/files/14.0.0.B2-14.0.0.RC1/files_delete.php @@ -1,6 +1,20 @@