1
0
Alex Trofimov 3 жил өмнө
parent
commit
c8e2af6b1d

+ 107 - 0
api.php

@@ -0,0 +1,107 @@
+<?php
+
+require_once('./inc/header.inc.php');
+require_once(BX_DIRECTORY_PATH_INC . "profiles.inc.php");
+require_once(BX_DIRECTORY_PATH_INC . "design.inc.php");
+
+define('BX_API', true);
+
+header('Content-Type: application/json');
+
+if (!getParam('sys_api_enable')) {
+    header('HTTP/1.0 403 Forbidden');
+    echo json_encode(['status' => 403, 'error' => _t("_Access denied")]);
+    exit;
+}
+
+$sOriginHeader = isset($_SERVER['HTTP_ORIGIN']) ? $_SERVER['HTTP_ORIGIN'] : false;
+$sAuthHeader = isset($_SERVER['HTTP_AUTHORIZATION']) ? $_SERVER['HTTP_AUTHORIZATION'] : false;
+
+if (getParam('sys_api_access_by_origin') && $sOriginHeader) {
+
+    if (parse_url($sOriginHeader, PHP_URL_HOST) != parse_url(BX_DOL_URL_ROOT, PHP_URL_HOST)) {
+
+        if (!BxDolApiQuery::getInstance()->getOrigin($sOriginHeader)) {
+            header('HTTP/1.0 403 Forbidden');
+            echo json_encode(['status' => 403, 'error' => _t("_Access denied")]);
+            exit;
+        }
+
+        header('Access-Control-Allow-Origin: ' . $sOriginHeader);
+        
+        if ('OPTIONS' == $_SERVER['REQUEST_METHOD']) {
+            header('Access-Control-Allow-Methods: POST, GET');
+            header('Access-Control-Allow-Headers: Accept-Encoding, Authorization, Cache-Control, Connection, Host, Origin, Pragma, Referer, User-Agent, X-Custom-Header, X-Requested-With');                    
+            exit;
+        }
+    }
+}
+elseif ($sAuthHeader && getParam('sys_api_access_by_key')) {
+    if (!BxDolApiQuery::getInstance()->getKey($sAuthHeader)) {
+        header('HTTP/1.0 403 Forbidden');
+        echo json_encode(['status' => 403, 'error' => _t("_Access denied")]);
+        exit;
+    }
+}
+else {
+    header('HTTP/1.0 403 Forbidden');
+    echo json_encode(['status' => 403, 'error' => _t("_Access denied")]);
+    exit;
+}
+
+$aRequest = isset($_GET['r']) ? explode('/', $_GET['r']) : [];
+
+$a = ['sModule', 'sMethod', 'sClass'];
+foreach ($aRequest as $i => $v)
+    if (isset($a[$i]) && preg_match('/^[A-Za-z0-9_-]+$/', $v))
+        ${$a[$i]} = $v;
+
+if (!isset($sClass))
+    $sClass = 'Module';
+
+foreach ($a as $v) {
+    if (!isset($$v)) {
+        header('HTTP/1.0 404 Not Found');
+        header('Status: 404 Not Found');
+        echo json_encode(['status' => 404, 'error' => _t("_sys_request_page_not_found_cpt")]);
+        exit;
+    }
+}
+
+if (!BxDolRequest::serviceExists($sModule, $sMethod, $sClass)) {
+    header('HTTP/1.0 404 Not Found');
+    header('Status: 404 Not Found');
+    echo json_encode(['status' => 404, 'error' => _t("_sys_request_page_not_found_cpt")]);
+    exit;
+}
+
+if (!($aParams = bx_get('params')))
+    $aParams = array();
+elseif (is_string($aParams) && preg_match('/^\[.*\]$/', $aParams))
+    $aParams = @json_decode($aParams);
+
+if (!is_array($aParams))
+    $aParams = array($aParams);
+
+$mixedRet = BxDolService::call($sModule, $sMethod, $aParams, $sClass);
+
+if (is_array($mixedRet) && isset($mixedRet['error'])) { 
+    header('HTTP/1.0 500 Internal Server Error');
+    header('Status: 500 Internal Server Error');
+    $a = [
+        'status' => 500, 
+        'error' => isset($mixedRet['desc']) ? $mixedRet['desc'] : $mixedRet['error']
+    ];
+    if (isset($mixedRet['code']))
+        $a['code'] = $mixedRet['code'];
+    echo json_encode($a);
+    exit;
+}
+
+echo json_encode([
+    'status' => 200,
+    'module' => $sModule,
+    'method' => $sMethod,
+    'params' => $aParams,
+    'data' => $mixedRet,
+]);

+ 55 - 0
inc/classes/BxDolApiQuery.php

@@ -0,0 +1,55 @@
+<?php defined('BX_DOL') or die('hack attempt');
+/**
+ * Copyright (c) UNA, Inc - https://una.io
+ * MIT License - https://opensource.org/licenses/MIT
+ *
+ * @defgroup    UnaCore UNA Core
+ * @{
+ */
+
+/**
+ * Database queries for API interface
+ * @see BxDolApiQuery
+ */
+class BxDolApiQuery extends BxDolDb implements iBxDolSingleton
+{
+    protected function __construct()
+    {
+        if (isset($GLOBALS['bxDolClasses'][get_class($this)]))
+            trigger_error ('Multiple instances are not allowed for the class: ' . get_class($this), E_USER_ERROR);
+
+        parent::__construct();
+    }
+
+    /**
+     * Prevent cloning the instance
+     */
+    public function __clone()
+    {
+        if (isset($GLOBALS['bxDolClasses'][get_class($this)]))
+            trigger_error('Clone is not allowed for the class: ' . get_class($this), E_USER_ERROR);
+    }
+
+    /**
+     * Get singleton instance of the class
+     */
+    static function getInstance()
+    {
+        if(!isset($GLOBALS['bxDolClasses'][__CLASS__]))
+            $GLOBALS['bxDolClasses'][__CLASS__] = new BxDolApiQuery();
+
+        return $GLOBALS['bxDolClasses'][__CLASS__];
+    }
+
+    public function getOrigin ($sUrl)
+    {
+        return $this->getOne("SELECT `url` FROM `sys_api_origins` WHERE `url` = ?", $sUrl);
+    }
+
+    public function getKey ($sKey)
+    {
+        return $this->getOne("SELECT `key` FROM `sys_api_keys` WHERE `key` = ?", $sKey);
+    }
+}
+
+/** @} */

+ 54 - 0
install/sql/system.sql

@@ -696,6 +696,20 @@ INSERT INTO `sys_options`(`category_id`, `name`, `caption`, `value`, `type`, `ex
 (@iCategoryId, 'sys_audit_max_records', '_adm_stg_cpt_option_sys_audit_max_records', '10000', 'digit', '', '', '', 2),
 (@iCategoryId, 'sys_audit_days_before_expire', '_adm_stg_cpt_option_sys_audit_days_before_expire', '365', 'digit', '', '', '', 3),
 (@iCategoryId, 'sys_audit_acl_levels', '_adm_stg_cpt_option_sys_audit_acl_levels', '7,8', 'list', 'a:4:{s:6:"module";s:6:"system";s:6:"method";s:15:"get_memberships";s:6:"params";a:0:{}s:5:"class";s:18:"TemplAuditServices";}', '', '', 4);
+
+
+--
+-- CATEGORY (HIDDEN): API
+--
+INSERT INTO `sys_options_categories`(`type_id`, `name`, `caption`, `hidden`, `order`) VALUES (@iTypeId, 'api', '_adm_stg_cpt_category_api', 1, 2);
+SET @iCategoryId = LAST_INSERT_ID();
+
+INSERT INTO `sys_options`(`category_id`, `name`, `caption`, `value`, `type`, `extra`, `check`, `check_error`, `order`) VALUES
+(@iCategoryId, 'sys_api_enable', '_adm_stg_cpt_option_sys_api_enable', '', 'checkbox', '', '', '', 1),
+(@iCategoryId, 'sys_api_access_by_origin', '_adm_stg_cpt_option_sys_api_access_by_origin', '', 'checkbox', '', '', '', 10),
+(@iCategoryId, 'sys_api_access_by_key', '_adm_stg_cpt_option_sys_api_access_by_key', '', 'checkbox', '', '', '', 20),
+(@iCategoryId, 'sys_api_access_unsafe_services', '_adm_stg_cpt_option_sys_api_access_unsafe_services', '', 'checkbox', '', '', '', 30);
+
 --
 -- Table structure for table `sys_options_mixes`
 --
@@ -5162,6 +5176,35 @@ INSERT INTO `sys_grid_fields` (`object`, `name`, `title`, `width`, `translatable
 INSERT INTO `sys_grid_actions` (`object`, `type`, `name`, `title`, `icon`, `icon_only`, `confirm`, `order`) VALUES
 ('sys_queues', 'single', 'clear', '', 'eraser', 0, 1, 1);
 
+-- GRID: API Origins
+
+INSERT INTO `sys_objects_grid` (`object`, `source_type`, `source`, `table`, `field_id`, `field_order`, `field_active`, `paginate_url`, `paginate_per_page`, `paginate_simple`, `paginate_get_start`, `paginate_get_per_page`, `filter_fields`, `filter_fields_translatable`, `filter_mode`, `sorting_fields`, `sorting_fields_translatable`, `override_class_name`, `override_class_file`) VALUES
+('sys_studio_api_origins', 'Sql', 'SELECT * FROM `sys_api_origins` WHERE 1 ', 'sys_api_origins', 'id', 'order', '', '', 20, NULL, 'start', '', 'url', '', 'like', '', '', 'BxDolStudioApiOrigins', '');
+
+INSERT INTO `sys_grid_fields` (`object`, `name`, `title`, `width`, `translatable`, `chars_limit`, `params`, `hidden_on`, `order`) VALUES
+('sys_studio_api_origins', 'order', '', '1%', 0, 0, '', '', 1),
+('sys_studio_api_origins', 'url', '_sys_txt_url', '80%', 0, 0, '', '', 2),
+('sys_studio_api_origins', 'actions', '', '19%', 0, 0, '', '', 3);
+
+INSERT INTO `sys_grid_actions` (`object`, `type`, `name`, `title`, `icon`, `icon_only`, `confirm`, `order`) VALUES
+('sys_studio_api_origins', 'single', 'delete', '_Delete', 'remove', 1, 1, 1),
+('sys_studio_api_origins', 'independent', 'add', '_adm_form_btn_field_add', '', 0, 0, 1);
+
+-- GRID: API Keys
+
+INSERT INTO `sys_objects_grid` (`object`, `source_type`, `source`, `table`, `field_id`, `field_order`, `field_active`, `paginate_url`, `paginate_per_page`, `paginate_simple`, `paginate_get_start`, `paginate_get_per_page`, `filter_fields`, `filter_fields_translatable`, `filter_mode`, `sorting_fields`, `sorting_fields_translatable`, `override_class_name`, `override_class_file`) VALUES
+('sys_studio_api_keys', 'Sql', 'SELECT * FROM `sys_api_keys` WHERE 1 ', 'sys_api_keys', 'id', 'order', '', '', 20, NULL, 'start', '', 'key,title', '', 'like', '', '', 'BxDolStudioApiKeys', '');
+
+INSERT INTO `sys_grid_fields` (`object`, `name`, `title`, `width`, `translatable`, `chars_limit`, `params`, `hidden_on`, `order`) VALUES
+('sys_studio_api_keys', 'order', '', '1%', 0, 0, '', '', 1),
+('sys_studio_api_keys', 'title', '_Name', '40%', 0, 0, '', '', 2),
+('sys_studio_api_keys', 'key', '_sys_txt_api_key', '40%', 0, 0, '', '', 3),
+('sys_studio_api_keys', 'actions', '', '19%', 0, 0, '', '', 4);
+
+INSERT INTO `sys_grid_actions` (`object`, `type`, `name`, `title`, `icon`, `icon_only`, `confirm`, `order`) VALUES
+('sys_studio_api_keys', 'single', 'delete', '_Delete', 'remove', 1, 1, 1),
+('sys_studio_api_keys', 'independent', 'add', '_adm_form_btn_field_add', '', 0, 0, 1);
+
 -- --------------------------------------------------------
 
 
@@ -6267,6 +6310,10 @@ INSERT INTO `sys_std_pages`(`index`, `name`, `header`, `caption`, `icon`) VALUES
 (3, 'badges', '_adm_page_cpt_badges', '_adm_page_cpt_badges', 'wi-badges.svg');
 SET @iIdBadges = LAST_INSERT_ID();
 
+INSERT INTO `sys_std_pages`(`index`, `name`, `header`, `caption`, `icon`) VALUES
+(3, 'api', '_adm_page_cpt_api', '_adm_page_cpt_api', 'wi-api.svg');
+SET @iIdAPI = LAST_INSERT_ID();
+
 --
 -- Dumping data for table `sys_std_widgets` and `sys_std_pages_widgets`
 -- Home Page
@@ -6346,3 +6393,10 @@ INSERT INTO `sys_std_pages_widgets`(`page_id`, `widget_id`, `order`) VALUES(@iId
 INSERT INTO `sys_std_widgets`(`page_id`, `module`, `type`, `url`, `click`, `icon`, `caption`, `cnt_notices`, `cnt_actions`) VALUES
 (@iIdBadges, 'system', 'structure', '{url_studio}badges.php', '', 'wi-badges.svg', '_adm_wgt_cpt_badges', '', 'a:4:{s:6:"module";s:6:"system";s:6:"method";s:11:"get_actions";s:6:"params";a:0:{}s:5:"class";s:18:"TemplStudioModules";}');
 INSERT INTO `sys_std_pages_widgets`(`page_id`, `widget_id`, `order`) VALUES(@iIdHome, LAST_INSERT_ID(), 13);
+
+--
+-- API Page
+--
+INSERT INTO `sys_std_widgets`(`page_id`, `module`, `type`, `url`, `click`, `icon`, `caption`, `cnt_notices`, `cnt_actions`) VALUES
+(@iIdAPI, 'system', 'appearance', '{url_studio}api.php', '', 'wi-api.svg', '_adm_wgt_cpt_api', '', 'a:4:{s:6:"module";s:6:"system";s:6:"method";s:11:"get_actions";s:6:"params";a:0:{}s:5:"class";s:18:"TemplStudioModules";}');
+INSERT INTO `sys_std_pages_widgets`(`page_id`, `widget_id`, `order`) VALUES(@iIdHome, LAST_INSERT_ID(), 14);

+ 10 - 0
modules/boonex/english/data/langs/system/en.xml

@@ -1115,6 +1115,7 @@
 	<string name="_adm_lmi_cpt_levels"><![CDATA[Levels]]></string>
 	<string name="_adm_lmi_cpt_logo"><![CDATA[Logo]]></string>
 	<string name="_adm_lmi_cpt_menus"><![CDATA[Menus]]></string>
+	<string name="_adm_lmi_cpt_origins"><![CDATA[Origins]]></string>
 	<string name="_adm_lmi_cpt_pre_lists"><![CDATA[Data Lists]]></string>
 	<string name="_adm_lmi_cpt_pre_values"><![CDATA[Data Items]]></string>
 	<string name="_adm_lmi_cpt_popular"><![CDATA[Popular]]></string>
@@ -1272,6 +1273,7 @@
         <string name="_adm_nav_txt_block_hidden_on_col_half"><![CDATA[Half]]></string>
         <string name="_adm_nav_txt_block_hidden_on_col_wide"><![CDATA[Wide]]></string>
         <string name="_adm_nav_txt_block_hidden_on_col_full"><![CDATA[Full]]></string>
+        <string name="_adm_page_cpt_api"><![CDATA[API]]></string>
         <string name="_adm_page_cpt_audit"><![CDATA[Audit]]></string>
         <string name="_adm_page_cpt_badges"><![CDATA[Badges]]></string>
 	<string name="_adm_page_cpt_builder_forms"><![CDATA[Forms]]></string>
@@ -1497,6 +1499,7 @@
     <string name="_adm_stg_cpt_category_twilio_gate"><![CDATA[Twilio]]></string>
     <string name="_adm_stg_cpt_category_location"><![CDATA[Location]]></string>
     <string name="_adm_stg_cpt_category_social_settings"><![CDATA[Social Settings]]></string>
+    <string name="_adm_stg_cpt_category_api"><![CDATA[API]]></string>
     <string name="_adm_stg_cpt_option_client_image_resize_width"><![CDATA[Image width to resize before upload (0 - disable)]]></string>
     <string name="_adm_stg_cpt_option_client_image_resize_height"><![CDATA[Image height to resize before upload (0 - disable)]]></string>
     <string name="_adm_stg_cpt_option_currency_code"><![CDATA[Currency code (for checkout system)]]></string>
@@ -1706,6 +1709,10 @@
     <string name="_adm_stg_cpt_option_sys_create_post_form_preloading_list"><![CDATA[Preload forms asynchronously in "Create Post" blocks]]></string>
     <string name="_adm_stg_cpt_option_sys_a2a_enable"><![CDATA[Use Add2Any code instead of default sharing menu]]></string>
     <string name="_adm_stg_cpt_option_sys_a2a_code"><![CDATA[Add2Any code]]></string>
+    <string name="_adm_stg_cpt_option_sys_api_enable"><![CDATA[Enable API]]></string>
+    <string name="_adm_stg_cpt_option_sys_api_access_by_origin"><![CDATA[Allow access by origin]]></string>
+    <string name="_adm_stg_cpt_option_sys_api_access_by_key"><![CDATA[Allow access with API key]]></string>
+    <string name="_adm_stg_cpt_option_sys_api_access_unsafe_services"><![CDATA[Access to unsafe services]]></string>
 
 	<string name="_adm_stg_cpt_type_system"><![CDATA[System]]></string>
 	<string name="_adm_stg_scs_save"><![CDATA[Settings were successfully saved]]></string>
@@ -1862,6 +1869,7 @@
 	<string name="_adm_txt_show_help"><![CDATA[Help]]></string>
 	<string name="_adm_txt_show_help_content_empty"><![CDATA[Help is not available]]></string>
 	<string name="_adm_txt_uninstall"><![CDATA[Uninstall]]></string>
+        <string name="_adm_wgt_cpt_api"><![CDATA[API]]></string>
         <string name="_adm_wgt_cpt_audit"><![CDATA[Audit]]></string>
         <string name="_adm_wgt_cpt_badges"><![CDATA[Badges]]></string>
 	<string name="_adm_wgt_cpt_builder_forms"><![CDATA[Forms]]></string>
@@ -3535,6 +3543,7 @@ If it is not enabled then please consider implement this optimization, since it
 	<string name="_sys_tour_homepage_account_menu_title"><![CDATA[Get to know your Account Menu]]></string>
 	<string name="_sys_tour_homepage_account_menu_txt"><![CDATA[Add and manage profiles, check notifications, access account settings. Admins and Moderators can use it to access Dash with links to site content and profiles management.]]></string>
 
+    <string name="_sys_txt_api_key"><![CDATA[API Key]]></string>
 	<string name="_sys_txt_access_denied"><![CDATA[Access denied]]></string>
 	<string name="_sys_txt_account_pending"><![CDATA[Your account is pending approval, please wait until it is activated.]]></string>
 	<string name="_sys_txt_account_profile_context_change_suggestion"><![CDATA[This is your profile, you can <a href="{0}">change your current profile</a> to this profile]]></string>
@@ -3660,6 +3669,7 @@ If it is not enabled then please consider implement this optimization, since it
 	<string name="_sys_txt_unsubscribe_error_occured"><![CDATA[Error occurred, please login to your account and update email references there or contact site administrator to unsubscribe you manually.]]></string>
 	<string name="_sys_txt_unsubscribe_info"><![CDATA[Update email preferences for <b>{0}</b>]]></string>
         <string name="_sys_txt_unsubscribe_wrong_link"><![CDATA[Unsubscribe link is wrong.]]></string>
+        <string name="_sys_txt_url"><![CDATA[URL]]></string>
         <string name="_sys_txt_user_n"><![CDATA[User #{0}]]></string>
         <string name="_sys_txt_reports_title"><![CDATA[Reports]]></string>
         <string name="_sys_txt_reports_grid_view_notes"><![CDATA[View notes]]></string>

+ 9 - 0
modules/boonex/russian/data/langs/system/ru.xml

@@ -1257,6 +1257,7 @@
         <string name="_adm_nav_txt_block_hidden_on_col_half"><![CDATA[Половина]]></string>
         <string name="_adm_nav_txt_block_hidden_on_col_wide"><![CDATA[Широкая]]></string>
         <string name="_adm_nav_txt_block_hidden_on_col_full"><![CDATA[Полная]]></string>
+        <string name="_adm_page_cpt_api"><![CDATA[API]]></string>
         <string name="_adm_page_cpt_audit"><![CDATA[Аудит]]></string>
         <string name="_adm_page_cpt_badges"><![CDATA[Бейджи]]></string>
 	<string name="_adm_page_cpt_builder_forms"><![CDATA[Формы]]></string>
@@ -1476,6 +1477,7 @@
     <string name="_adm_stg_cpt_category_twilio_gate"><![CDATA[Twilio]]></string>
     <string name="_adm_stg_cpt_category_location"><![CDATA[Местоположение]]></string>
     <string name="_adm_stg_cpt_category_social_settings"><![CDATA[Социальные настройки]]></string>
+    <string name="_adm_stg_cpt_category_api"><![CDATA[API]]></string>
     <string name="_adm_stg_cpt_option_client_image_resize_width"><![CDATA[Изменять ширину картинки перед загрузкой (0 - отключить)]]></string>
     <string name="_adm_stg_cpt_option_client_image_resize_height"><![CDATA[Изменять высоту картинки перед загрузкой (0 - отключить)]]></string>    
     <string name="_adm_stg_cpt_option_currency_code"><![CDATA[Код валюты (для платёжных систем)]]></string>
@@ -1685,6 +1687,11 @@
     <string name="_adm_stg_cpt_option_sys_create_post_form_preloading_list"><![CDATA[Предварительно загружать формы в асинхронном режиме в "Создать пост" блоках]]></string>
     <string name="_adm_stg_cpt_option_sys_a2a_enable"><![CDATA[Использовать Add2Any код вместо стандартного меню "Поделиться"]]></string>
     <string name="_adm_stg_cpt_option_sys_a2a_code"><![CDATA[Add2Any код]]></string>
+    <string name="_adm_stg_cpt_option_sys_api_enable"><![CDATA[Включить API]]></string>
+    <string name="_adm_stg_cpt_option_sys_api_access_by_origin"><![CDATA[Доступ по "origin" заголовку]]></string>
+    <string name="_adm_stg_cpt_option_sys_api_access_by_key"><![CDATA[Доступ по API ключу]]></string>
+    <string name="_adm_stg_cpt_option_sys_api_access_unsafe_services"><![CDATA[Доступ к небезопасным сервисам]]></string>
+
     <string name="_adm_stg_cpt_type_system"><![CDATA[Система]]></string>
     <string name="_adm_stg_scs_save"><![CDATA[Настройки удачно сохранены]]></string>
     <string name="_adm_stg_err_save_error_message"><![CDATA[Ошибка в '{0}': {1}]]></string>
@@ -1840,6 +1847,7 @@
 	<string name="_adm_txt_show_help"><![CDATA[Помощь]]></string>
 	<string name="_adm_txt_show_help_content_empty"><![CDATA[Помошь недоступна]]></string>
 	<string name="_adm_txt_uninstall"><![CDATA[Демонтировать]]></string>
+        <string name="_adm_wgt_cpt_api"><![CDATA[API]]></string>
         <string name="_adm_wgt_cpt_audit"><![CDATA[Аудит]]></string>
         <string name="_adm_wgt_cpt_badges"><![CDATA[Бейджи]]></string>
 	<string name="_adm_wgt_cpt_builder_forms"><![CDATA[Формы]]></string>
@@ -3462,6 +3470,7 @@
 	<string name="_sys_tour_homepage_account_menu_title"><![CDATA[Узнай меню своей учётной записи]]></string>
 	<string name="_sys_tour_homepage_account_menu_txt"><![CDATA[Здесь можно добавлять и управлять профилями, следить за уведомлениями, открывать настройки своей учётной записи. Администраторы и модераторы сайта могут использовать это меню, чтобы открыть приборную панель со ссылками по администрации сайта.]]></string>
 
+    <string name="_sys_txt_api_key"><![CDATA[Ключ API]]></string>
     <string name="_sys_txt_access_denied"><![CDATA[Доступ запрещён]]></string>
     <string name="_sys_txt_account_pending"><![CDATA[Ваш аккаунт ожидает одобрения, пожалуйста, дождитесь его активации.]]></string>
     <string name="_sys_txt_account_profile_context_change_suggestion"><![CDATA[Это Ваш профиль, Вы можете <a href="{0}">изменить свой текущий профиль</a> на этот]]></string>

+ 38 - 0
studio/api.php

@@ -0,0 +1,38 @@
+<?php
+/**
+ * Copyright (c) UNA, Inc - https://una.io
+ * MIT License - https://opensource.org/licenses/MIT
+ *
+ * @defgroup    UnaEndAdmin UNA Studio End Admin Pages
+ * @ingroup     UnaStudio
+ * @{
+ */
+
+require_once('./../inc/header.inc.php');
+require_once(BX_DIRECTORY_PATH_INC . 'design.inc.php');
+
+bx_import('BxDolLanguages');
+
+bx_require_authentication(true);
+
+$sPage = bx_get('page');
+$sPage = $sPage !== false ? bx_process_input($sPage) : '';
+
+$oPage = new BxTemplStudioAPI($sPage);
+
+$oTemplate = BxDolStudioTemplate::getInstance();
+
+$sPageCode = $oPage->getPageCode();
+if($sPageCode === false)
+    $oTemplate->displayMsg(($sError = $oPage->getError(false)) !== false ? $sError : '_sys_txt_error_occured', true);
+
+$oTemplate->setPageNameIndex($oPage->getPageIndex());
+$oTemplate->setPageHeader($oPage->getPageHeader());
+$oTemplate->setPageContent('page_caption_code', $oPage->getPageCaption());
+$oTemplate->setPageContent('page_attributes', $oPage->getPageAttributes());
+$oTemplate->setPageContent('page_menu_code', $oPage->getPageMenu());
+$oTemplate->setPageContent('page_main_code', $sPageCode . $oPage->getPageJsCode());
+$oTemplate->addCss($oPage->getPageCss());
+$oTemplate->addJs($oPage->getPageJs());
+$oTemplate->getPageCode();
+/** @} */

+ 30 - 0
studio/classes/BxDolStudioAPI.php

@@ -0,0 +1,30 @@
+<?php defined('BX_DOL') or die('hack attempt');
+/**
+ * Copyright (c) UNA, Inc - https://una.io
+ * MIT License - https://opensource.org/licenses/MIT
+ *
+ * @defgroup    UnaStudio UNA Studio
+ * @{
+ */
+
+define('BX_DOL_STUDIO_API_TYPE_SETTINGS', 'settings');
+define('BX_DOL_STUDIO_API_TYPE_KEYS', 'keys');
+define('BX_DOL_STUDIO_API_TYPE_ORIGINS', 'origins');
+
+define('BX_DOL_STUDIO_API_TYPE_DEFAULT', BX_DOL_STUDIO_API_TYPE_SETTINGS);
+
+class BxDolStudioAPI extends BxTemplStudioWidget
+{
+    protected $sPage;
+
+    function __construct($sPage = "")
+    {
+        parent::__construct('api');
+
+        $this->sPage = BX_DOL_STUDIO_API_TYPE_DEFAULT;
+        if(is_string($sPage) && !empty($sPage))
+            $this->sPage = $sPage;
+    }
+}
+
+/** @} */

+ 148 - 0
studio/classes/BxDolStudioApiKeys.php

@@ -0,0 +1,148 @@
+<?php defined('BX_DOL') or die('hack attempt');
+/**
+ * Copyright (c) UNA, Inc - https://una.io
+ * MIT License - https://opensource.org/licenses/MIT
+ *
+ * @defgroup    UnaStudio UNA Studio
+ * @{
+ */
+
+class BxDolStudioApiKeys extends BxTemplStudioGrid
+{
+    public function __construct ($aOptions, $oTemplate = false)
+    {
+        parent::__construct ($aOptions, $oTemplate);
+    }
+
+    public function _performActionAdd($aForm, $aCustomValues = []) 
+    {
+        $oForm = new BxTemplFormView($aForm);
+        $oForm->initChecker();
+
+        if ($oForm->isSubmittedAndValid()) { // if form is submitted and all fields are valid
+
+            $iRecentId = $oForm->insert ($aCustomValues, true); // insert new record
+
+            if ($iRecentId)
+                $aRes = array('grid' => $this->getCode(false), 'blink' => $iRecentId); // if record is successfully added, reload grid and highlight added row
+            else
+                $aRes = array('msg' => _t('_sys_txt_error_occured')); // if record adding failed, display error message
+
+            echoJson($aRes);
+
+        } else { // if form is not submitted or some fields are invalid, display popup with form
+
+            $s = BxTemplFunctions::getInstance()->popupBox($oForm->getId() . '_form', '', $oForm->getCode() . '
+                <script>
+                    $(document).ready(function () {
+                        $("#' . $oForm->getId() . '").ajaxForm({
+                            dataType: "json",
+                            beforeSubmit: function (formData, jqForm, options) {
+                                bx_loading($("#' . $oForm->getId() . '"), true);
+                            },
+                            success: function (data) {
+                                $(".bx-popup-applied:visible").dolPopupHide();
+                                glGrids.' . $this->_sObject . '.processJson(data, "add");
+                            }
+                        });
+                    });
+                </script>');
+
+            echoJson(array('popup' => array('html' => $s, 'options' => array('closeOnOuterClick' => false))));
+
+        }
+    }
+
+    public function performActionAdd()
+    {
+        $aForm = array(
+            'form_attrs' => array(
+                'id' => 'bx_studio_api_keys',
+                'action' => BX_DOL_URL_ROOT . 'grid.php?o=sys_studio_api_keys&a=add',
+                'method' => 'post',
+            ),
+            'params' => array (
+                'db' => array(
+                    'table' => 'sys_api_keys',
+                    'key' => 'id',
+                    'submit_name' => 'do_submit',
+                ),
+            ),
+            'inputs' => array(
+
+                'title' => array(
+                    'type' => 'text',
+                    'name' => 'title',
+                    'caption' => _t('_Name'),
+                    'db' => array (
+                        'pass' => 'Xss',
+                    ),
+                ),
+
+                'submit' => array(
+                    'type' => 'input_set',
+                    0 => array (
+                        'type' => 'submit',
+                        'name' => 'do_submit',
+                        'value' => _t('_sys_submit'),
+                    ),
+                    1 => array (
+                        'type' => 'reset',
+                        'name' => 'close',
+                        'value' => _t('_sys_close'),
+                        'attrs' => array('class' => 'bx-def-margin-sec-left', 'onclick' => '$(\'.bx-popup-applied:visible\').dolPopupHide();'),
+                    ),
+                ),
+
+            ),
+        );
+
+        $aCustomValues = array(
+            'key' => genRndPwd(48),
+        );
+        return $this->_performActionAdd($aForm, $aCustomValues);
+/*
+        $oForm = new BxTemplFormView($aForm);
+        $oForm->initChecker();
+
+        if ($oForm->isSubmittedAndValid()) { // if form is submitted and all fields are valid
+
+            $aCustomValues = array(
+                'key' => genRndPwd(48),
+            );
+
+            $iRecentId = $oForm->insert ($aCustomValues, true); // insert new record
+
+            if ($iRecentId)
+                $aRes = array('grid' => $this->getCode(false), 'blink' => $iRecentId); // if record is successfully added, reload grid and highlight added row
+            else
+                $aRes = array('msg' => _t('_sys_txt_error_occured')); // if record adding failed, display error message
+
+            echoJson($aRes);
+
+        } else { // if form is not submitted or some fields are invalid, display popup with form
+
+            $s = BxTemplFunctions::getInstance()->popupBox($oForm->getId() . '_form', '', $oForm->getCode() . '
+                <script>
+                    $(document).ready(function () {
+                        $("#' . $oForm->getId() . '").ajaxForm({
+                            dataType: "json",
+                            beforeSubmit: function (formData, jqForm, options) {
+                                bx_loading($("#' . $oForm->getId() . '"), true);
+                            },
+                            success: function (data) {
+                                $(".bx-popup-applied:visible").dolPopupHide();
+                                glGrids.' . $this->_sObject . '.processJson(data, "add");
+                            }
+                        });
+                    });
+                </script>');
+
+            echoJson(array('popup' => array('html' => $s, 'options' => array('closeOnOuterClick' => false))));
+
+        }
+*/
+    }
+}
+
+/** @} */

+ 65 - 0
studio/classes/BxDolStudioApiOrigins.php

@@ -0,0 +1,65 @@
+<?php defined('BX_DOL') or die('hack attempt');
+/**
+ * Copyright (c) UNA, Inc - https://una.io
+ * MIT License - https://opensource.org/licenses/MIT
+ *
+ * @defgroup    UnaStudio UNA Studio
+ * @{
+ */
+
+class BxDolStudioApiOrigins extends BxDolStudioApiKeys
+{
+    public function __construct ($aOptions, $oTemplate = false)
+    {
+        parent::__construct ($aOptions, $oTemplate);
+    }
+
+    public function performActionAdd()
+    {
+        $aForm = array(
+            'form_attrs' => array(
+                'id' => 'bx_studio_api_origins',
+                'action' => BX_DOL_URL_ROOT . 'grid.php?o=sys_studio_api_origins&a=add',
+                'method' => 'post',
+            ),
+            'params' => array (
+                'db' => array(
+                    'table' => 'sys_api_origins',
+                    'key' => 'id',
+                    'submit_name' => 'do_submit',
+                ),
+            ),
+            'inputs' => array(
+
+                'url' => array(
+                    'type' => 'text',
+                    'name' => 'url',
+                    'caption' => _t('_sys_txt_url'),
+                    'db' => array (
+                        'pass' => 'Xss',
+                    ),
+                ),
+
+                'submit' => array(
+                    'type' => 'input_set',
+                    0 => array (
+                        'type' => 'submit',
+                        'name' => 'do_submit',
+                        'value' => _t('_sys_submit'),
+                    ),
+                    1 => array (
+                        'type' => 'reset',
+                        'name' => 'close',
+                        'value' => _t('_sys_close'),
+                        'attrs' => array('class' => 'bx-def-margin-sec-left', 'onclick' => '$(\'.bx-popup-applied:visible\').dolPopupHide();'),
+                    ),
+                ),
+
+            ),
+        );
+
+        return $this->_performActionAdd($aForm);
+    }
+}
+
+/** @} */

Файлын зөрүү хэтэрхий том тул дарагдсан байна
+ 5 - 0
studio/template/images/icons/wi-api.svg


+ 93 - 0
studio/template/scripts/BxBaseStudioAPI.php

@@ -0,0 +1,93 @@
+<?php defined('BX_DOL') or die('hack attempt');
+/**
+ * Copyright (c) UNA, Inc - https://una.io
+ * MIT License - https://opensource.org/licenses/MIT
+ *
+ * @defgroup    UnaView UNA Studio Representation classes
+ * @ingroup     UnaStudio
+ * @{
+ */
+
+class BxBaseStudioAPI extends BxDolStudioAPI
+{
+    protected $sSubpageUrl;
+    protected $aMenuItems;
+    protected $aGridObjects;
+
+    public function __construct($sPage = '')
+    {
+        parent::__construct($sPage);
+
+        $this->aPageCss = array_merge($this->aPageCss, ['forms.css', 'paginate.css']);
+        
+        $this->sSubpageUrl = BX_DOL_URL_STUDIO . 'api.php?page=';
+
+        $this->aMenuItems = array(
+            BX_DOL_STUDIO_API_TYPE_SETTINGS => array('icon' => 'cogs'),
+            BX_DOL_STUDIO_API_TYPE_ORIGINS => array('icon' => 'globe'),
+            BX_DOL_STUDIO_API_TYPE_KEYS => array('icon' => 'key'),
+        );
+
+        $this->aGridObjects = array(
+            'keys' => 'sys_studio_api_keys',
+            'origins' => 'sys_studio_api_origins',
+        );
+    }
+
+    public function getPageJsCode($aOptions = array(), $bWrap = true)
+    {
+        $aOptions = array_merge($aOptions, array(
+            'sActionUrl' => BX_DOL_URL_STUDIO . 'api.php'
+        ));
+
+        return parent::getPageJsCode($aOptions, $bWrap);
+    }
+
+    public function getPageMenu($aMenu = array(), $aMarkers = array())
+    {
+        $sJsObject = $this->getPageJsObject();
+
+        $aMenu = array();
+        foreach($this->aMenuItems as $sMenuItem => $aItem)
+            $aMenu[] = array(
+                'name' => $sMenuItem,
+                'icon' => $aItem['icon'],
+                'link' => $this->sSubpageUrl . $sMenuItem,
+                'title' => _t('_adm_lmi_cpt_' . $sMenuItem),
+                'selected' => $sMenuItem == $this->sPage
+            );
+
+        return parent::getPageMenu($aMenu);
+    }
+
+    protected function getSettings()
+    {
+        $oOptions = new BxTemplStudioOptions(BX_DOL_STUDIO_STG_TYPE_DEFAULT, 'api');
+
+        $this->aPageCss = array_merge($this->aPageCss, $oOptions->getCss());
+        $this->aPageJs = array_merge($this->aPageJs, $oOptions->getJs());
+        
+        return $oOptions->getCode();
+    }
+
+    protected function getKeys()
+    {
+        return $this->getGrid($this->aGridObjects['keys']);
+    }
+
+    protected function getOrigins()
+    {
+        return $this->getGrid($this->aGridObjects['origins']);
+    }
+
+    protected function getGrid($sObjectName)
+    {
+        $oGrid = BxDolGrid::getObjectInstance($sObjectName);
+        if(!$oGrid)
+            return '';
+
+        return $oGrid->getCode();
+    }
+}
+
+/** @} */

+ 19 - 0
studio/template/scripts_templ/BxTemplStudioAPI.php

@@ -0,0 +1,19 @@
+<?php
+/**
+ * Copyright (c) UNA, Inc - https://una.io
+ * MIT License - https://opensource.org/licenses/MIT
+ *
+ * @defgroup    UnaStudioView UNA Studio Representation classes
+ * @ingroup     UnaStudio
+ * @{
+ */
+defined('BX_DOL') or die('hack attempt');
+
+class BxTemplStudioAPI extends BxBaseStudioAPI
+{
+    function __construct($sPage = '')
+    {
+        parent::__construct($sPage);
+    }
+}
+/** @} */

Энэ ялгаанд хэт олон файл өөрчлөгдсөн тул зарим файлыг харуулаагүй болно