Browse Source

Ticket #5569 - API: Add full support for Wiki module.

AntonLV 3 months ago
parent
commit
09d17278b8

+ 4 - 0
inc/classes/BxDolPage.php

@@ -115,6 +115,8 @@ class BxDolPage extends BxDolFactory implements iBxDolFactoryObject, iBxDolRepla
 {
     protected static $_aBlockProcessing = [];
 
+    protected $_bIsApi;
+
     protected $_sObject;
     protected $_aObject;
     protected $_oQuery;
@@ -130,6 +132,8 @@ class BxDolPage extends BxDolFactory implements iBxDolFactoryObject, iBxDolRepla
     {
         parent::__construct();
 
+        $this->_bIsApi = bx_is_api();
+
         $this->_sObject = $aObject['object'];
         $this->_aObject = $aObject;
         $this->_oQuery = new BxDolPageQuery($this->_aObject);

+ 2 - 2
inc/classes/BxDolPageQuery.php

@@ -117,9 +117,9 @@ class BxDolPageQuery extends BxDolDb
         return BxDolDb::getInstance()->getAll("SELECT * FROM `sys_pages_types` WHERE 1");
     }
 
-    public function getPageLayoutColumns($iLayoutId)
+    public function getPageLayoutColumns($iLayoutId, $sKey = 'index')
     {
-        return $this->getAllWithKey('SELECT * FROM `sys_pages_layout_columns` WHERE `layout_id`=:layout_id', 'index', [
+        return $this->getAllWithKey('SELECT * FROM `sys_pages_layout_columns` WHERE `layout_id`=:layout_id', $sKey, [
             'layout_id' => $iLayoutId
         ]);
     }

+ 136 - 78
inc/classes/BxDolWiki.php

@@ -140,6 +140,14 @@ class BxDolWiki extends BxDolFactory implements iBxDolFactoryObject
         return $this->_aObject['uri'];
     }
 
+    /**
+     * Get module name
+     */
+    public function getModule ()
+    {
+        return $this->_aObject['module'];
+    }
+
     /**
      * Get WIKI block content
      * @param $iBlockId block ID
@@ -151,35 +159,35 @@ class BxDolWiki extends BxDolFactory implements iBxDolFactoryObject
         if (!$sLang)
             $sLang = bx_lang_name();
 
-        $s = '';
-        $sControls = '';
+        $sContent = '';
         $aWikiVer = $this->_oQuery->getBlockContent ($iBlockId, $sLang, $iRevision);
         $aWikiLatest = $this->_oQuery->getBlockContent ($iBlockId, $sLang);
         if ($aWikiVer) {
             if ($this->_bProcessMarkdown && !$this->_bIsApi) {
                 $oParsedown = new BxDolParsedown();
                 $oParsedown->setSafeMode($aWikiVer['unsafe'] ? false : true);
-                $s = $oParsedown->text($aWikiVer['content']);
-            }
-            else {
-                $s = $aWikiVer['content'];
+                $sContent = $oParsedown->text($aWikiVer['content']);
             }
+            else
+                $sContent = $aWikiVer['content'];
         }
 
         if (!$aWikiVer && $aWikiLatest) {
-            return _t('_sys_wiki_error_no_rev', $iRevision ? $iRevision : 0, $sLang);
+            return ($sMsg = _t('_sys_wiki_error_no_rev', $iRevision ? $iRevision : 0, $sLang)) && $this->_bIsApi ? ['content' => $sMsg] : $sMsg;
         }
 
         if (!$aWikiVer && !$aWikiLatest && $this->isAllowed('edit')) {
-            $s = _t('_sys_wiki_error_no_revs');
+            $sContent = _t('_sys_wiki_error_no_revs');
         }
 
-        $sControls = '';
-        if (!$this->_bIsApi && ($aWikiVer || $this->isAllowed('edit'))) {
-            $sControls = BxDolService::call('system', 'wiki_controls', array($this, $aWikiVer, $aWikiLatest, $iBlockId), 'TemplServiceWiki');
-        }
+        $mixedControls = '';
+        if ($aWikiVer || $this->isAllowed('edit'))
+            $mixedControls = bx_srv('system', 'wiki_controls', [$this, $aWikiVer, $aWikiLatest, $iBlockId], 'TemplServiceWiki');
 
-        return $s . $sControls;
+        return $this->_bIsApi ? array_merge([
+            'content' => $sContent,
+            'menu' => ''
+        ], $mixedControls) : $sContent . $mixedControls;
     }
 
     /**
@@ -375,9 +383,11 @@ class BxDolWiki extends BxDolFactory implements iBxDolFactoryObject
             return array('code' => 0, 'language' => $aWikiVer['language'], 'content' => $aWikiVer['content'], 'block_id' => $aWikiVer['block_id']);
     }
 
-    public function actionDeleteVersion ()
+    public function actionDeleteVersion ($iBlockId = 0)
     {
-        $iBlockId = (int)bx_get('block_id');
+        if(!$iBlockId && ($_iBlockId = bx_get('block_id')) !== false)
+            $iBlockId = (int)$_iBlockId;
+
         $sLang = bx_lang_name();
         $oLang = BxDolLanguages::getInstance();
 
@@ -385,9 +395,9 @@ class BxDolWiki extends BxDolFactory implements iBxDolFactoryObject
         $aVars['select_all'] = _t('_Select_all');
 
         if (!$aVars['bx_repeat:revisions'])
-            return BxDolTemplate::getInstance()->parseHtmlByName('wiki_msg.html', array(
+            return ($sMsg = _t('_sys_wiki_error_no_revs')) && $this->_bIsApi ? [bx_api_get_msg($sMsg)] : BxDolTemplate::getInstance()->parseHtmlByName('wiki_msg.html', array(
                 'close' => _t('_sys_close'),
-                'msg' => _t('_sys_wiki_error_no_revs'),
+                'msg' => $sMsg,
             ));
 
         $aForm = array(
@@ -415,7 +425,7 @@ class BxDolWiki extends BxDolFactory implements iBxDolFactoryObject
                     'type' => 'custom',
                     'name' => 'revision',
                     'caption' => '',
-                    'content' => BxDolTemplate::getInstance()->parseHtmlByName('wiki_delete_version.html', $aVars),
+                    'content' => $this->_bIsApi ? $aVars : BxDolTemplate::getInstance()->parseHtmlByName('wiki_delete_version.html', $aVars),
                 ),
                 'buttons' => array(
                     'type' => 'input_set',
@@ -442,10 +452,15 @@ class BxDolWiki extends BxDolFactory implements iBxDolFactoryObject
 
         if ($oForm->isSubmittedAndValid ()) {
             $i = $this->_oQuery->deleteRevisions ($iBlockId, $sLang, bx_get('revision'));
-            return array('code' => 0, 'actions' => array('Reload', 'ClosePopup', 'ShowMsg'), 'block_id' => $iBlockId, 'msg' => _t('_sys_wiki_revisions_deleted', $i));
+            return ($sMsg = _t('_sys_wiki_revisions_deleted', $i)) && $this->_bIsApi ? [bx_api_get_msg($sMsg), ['ext' => ['code' => 0, 'block_id' => $iBlockId]]] : ['code' => 0, 'actions' => ['Reload', 'ClosePopup', 'ShowMsg'], 'block_id' => $iBlockId, 'msg' => $sMsg];
         }
         else {
-            return BxDolTemplate::getInstance()->parseHtmlByName('wiki_form.html', array(
+            return $this->_bIsApi ? [bx_api_get_block('form', $oForm->getCodeAPI(), [
+                'ext' => [
+                    'name' => $this->_sObject, 
+                    'request' => ['url' => '/api.php?r=system/wiki_action/TemplServiceWiki&params[]=' . $this->getUri() . '&params[]=delete-version&params[]=' . $iBlockId, 'immutable' => true]
+                ]
+            ])] : BxDolTemplate::getInstance()->parseHtmlByName('wiki_form.html', array(
                 'form' => $oForm->getCode(),
                 'block_id' => $iBlockId,
                 'wiki_action_uri' => $this->getUri(),
@@ -455,24 +470,26 @@ class BxDolWiki extends BxDolFactory implements iBxDolFactoryObject
         }
     }
 
-    public function actionAddPage ()
+    public function actionAddPage ($sPageUri = '')
     {
+        if(!$sPageUri && ($_sPage = bx_get('page')) !== false)
+            $sPageUri = bx_process_input($_sPage);
+
         // validate page URI
-        $sPageUri = strtolower(bx_get('page'));
-        if (!preg_match("/^[a-z0-9_-]+$/", $sPageUri))
-            return _t('_sys_wiki_error_incorrect_page_uri', bx_process_output($sPageUri));
+        if(!preg_match("/^[a-z0-9_-]+$/", $sPageUri))
+            return ($sMsg = _t('_sys_wiki_error_incorrect_page_uri', bx_process_output($sPageUri))) && $this->_bIsApi ? [bx_api_get_msg($sMsg)] : $sMsg;
 
         // check if such page exist
         $oPage1 = BxDolPage::getObjectInstanceByUri($sPageUri);
         $oPage2 = BxDolPage::getObjectInstance($this->_aObject['module'] . '_' . str_replace('-', '_', $sPageUri));
-        if ($oPage1 || $oPage2)
-            return _t('_sys_wiki_error_page_exists', bx_process_output($sPageUri));
+        if($oPage1 || $oPage2)
+            return ($sMsg = _t('_sys_wiki_error_page_exists', bx_process_output($sPageUri))) && $this->_bIsApi ? [bx_api_get_msg($sMsg)] : $sMsg;
 
         // get lang category where translations will be added
         $oLang = BxDolStudioLanguagesUtils::getInstance();
         $iLangCat = $oLang->getLanguageCategory($this->_sLangCateg);
-        if (!$iLangCat)
-            return _t('_sys_wiki_error_occured', 9);
+        if(!$iLangCat)
+            return ($sMsg = _t('_sys_wiki_error_occured', 9)) && $this->_bIsApi ? [bx_api_get_msg($sMsg)] : $sMsg;
 
         // set default values for the form
         $aValues = array();
@@ -537,101 +554,122 @@ class BxDolWiki extends BxDolFactory implements iBxDolFactoryObject
         $oForm = new BxTemplStudioFormView ($aForm);
         $oForm->initChecker();
 
-        if ($oForm->isSubmittedAndValid ()) {
-
+        if ($oForm->isSubmittedAndValid()) {
             // insert page
             $sLangKey = '_' . $this->_aObject['module'] . '_' . str_replace('-', '_', $sPageUri) . '_' . time();
             $iPageId = $this->addPage ($sPageUri, $sLangKey);
             if (!$iPageId)
-                return array('code' => 10, 'actions' => array('ShowMsg'), 'msg' => _t('_sys_wiki_error_occured', 10));
+                return ($sMsg = _t('_sys_wiki_error_occured', 10)) && $this->_bIsApi ? [bx_api_get_msg($sMsg, ['ext' => ['code' => 10]])] : ['code' => 10, 'actions' => ['ShowMsg'], 'msg' => $sMsg];
 
             // insert translations
             $aLangs = $oLang->getLanguages(true, true);
             foreach ($aLangs as $iLangId => $sLangTitle) {
                 $sLang = $oLang->getLangName($iLangId);
-                if (!($sVal = $oForm->getCleanValue('title-' . $sLang)))
+                if(!($sVal = $oForm->getCleanValue('title-' . $sLang)))
                     continue;
+
                 $oLang->addLanguageString($sLangKey, $sVal, $iLangId, $iLangCat);
             }
 
             $sUrl = $this->getPageUrl($sPageUri, false, false);
-            return array('code' => 0, 'url' => BxDolPermalinks::getInstance()->permalink($sUrl));
+            return ['code' => 0, 'url' => BxDolPermalinks::getInstance()->permalink($sUrl)];
         }
         else {
             // display form
-            return BxDolTemplate::getInstance()->parseHtmlByName('wiki_create_page_form.html', array(
+            return $this->_bIsApi ? [bx_api_get_block('form', $oForm->getCodeAPI(), [
+                'ext' => [
+                    'name' => $this->_sObject, 
+                    'request' => ['url' => '/api.php?r=system/wiki_action/TemplServiceWiki&params[]=' . $this->getUri() . '&params[]=add-page&params[]=' . $sPageUri, 'immutable' => true]
+                ]
+            ])] : BxDolTemplate::getInstance()->parseHtmlByName('wiki_create_page_form.html', [
                 'form' => $oForm->getCode(),
                 'wiki_action_uri' => $this->getUri(),
                 'action' => 'add-page',
-            ));
+            ]);
         }
     }
 
-    public function actionAdd ()
+    public function actionAdd($sPage = '', $iCellId = 0)
     {
-        $iCellId = (int)bx_get('cell_id');
-        $sPage = bx_get('page');
+        if(!$sPage && ($_sPage = bx_get('page')) !== false)
+            $sPage = bx_process_input($_sPage);
+
+        if(!$iCellId && ($_iCellId = bx_get('cell_id')) !== false)
+            $iCellId = (int)$_iCellId;
+
         $oPage = BxDolPage::getObjectInstance($sPage);
-        if (!$oPage)
-            return array('code' => 4, 'actions' => array('ShowMsg'), 'msg' => _t('_sys_wiki_error_occured', 4));
+        if(!$oPage)
+            return ($sMsg = _t('_sys_wiki_error_occured', 4)) && $this->_bIsApi ? [bx_api_get_msg($sMsg, ['ext' => ['code' => 4]])] : ['code' => 4, 'actions' => ['ShowMsg'], 'msg' => $sMsg];
 
-        if ($this->_aObject['module'] != $oPage->getModule())
-            return array('code' => 5, 'actions' => array('ShowMsg'), 'msg' => _t('_sys_txt_access_denied'));
+        if($this->_aObject['module'] != $oPage->getModule())
+            return ($sMsg = _t('_sys_txt_access_denied')) && $this->_bIsApi ? [bx_api_get_msg($sMsg, ['ext' => ['code' => 5]])] : ['code' => 5, 'actions' => ['ShowMsg'], 'msg' => $sMsg];
 
-        $iDesignBox = getParam($this->_aObject['module'] . '_design_box');
-        $aBlock = array(
+        $oQueryPageBuilder = new BxDolStudioBuilderPageQuery();
+        if(!($iBlockId = $oQueryPageBuilder->insertBlock([
             'object' => $sPage,
             'cell_id' => $iCellId,
             'module' => $this->_aObject['module'],
             'title_system' => '',
             'title' => '',
-            'designbox_id' => false === $iDesignBox ? 0 : $iDesignBox,
+            'designbox_id' => (int)getParam($this->_aObject['module'] . '_design_box'),
             'visible_for_levels' => 2147483647, 
             'type' => 'wiki',
             'deletable' => 1,
             'copyable' => 0,
             'active' => 1,
-        );
-        $oQueryPageBuilder = new BxDolStudioBuilderPageQuery();
-        if (!($iBlockId = $oQueryPageBuilder->insertBlock($aBlock)))
-            return array('code' => 6, 'actions' => array('ShowMsg'), 'msg' => _t('_sys_wiki_error_occured', 6));
+        ])))
+            return ($sMsg = _t('_sys_wiki_error_occured', 6)) && $this->_bIsApi ? [bx_api_get_msg($sMsg, ['ext' => ['code' => 6]])] : ['code' => 6, 'actions' => ['ShowMsg'], 'msg' => $sMsg];
 
-        return array('code' => 0, 'block_id' => $iBlockId, 'cell_id' => $iCellId);
+        return ['code' => 0, 'block_id' => $iBlockId, 'cell_id' => $iCellId];
     }
 
-    public function actionDeleteBlock ()
+    public function actionDeleteBlock ($iBlockId = 0)
     {
-        $iBlockId = (int)bx_get('block_id');
+        if(!$iBlockId && ($_iBlockId = bx_get('block_id')) !== false)
+            $iBlockId = (int)$_iBlockId;
 
         $oQueryPageBuilder = new BxDolStudioBuilderPageQuery();
-        if (!$oQueryPageBuilder->deleteBlocks(array('type' => 'by_id', 'value' => $iBlockId)))
-            return array('code' => 3, 'actions' => array('ShowMsg'), 'block_id' => $iBlockId, 'msg' => _t('_sys_wiki_error_occured', 3));
+        if (!$oQueryPageBuilder->deleteBlocks(['type' => 'by_id', 'value' => $iBlockId]))
+            return ($sMsg = _t('_sys_wiki_error_occured', 3)) && $this->_bIsApi ? [bx_api_get_msg($sMsg, ['ext' => ['code' => 3, 'block_id' => $iBlockId]])] : ['code' => 3, 'actions' => ['ShowMsg'], 'block_id' => $iBlockId, 'msg' => $sMsg];
 
         self::onBlockDelete($iBlockId);
 
-        return array('code' => 0, 'actions' => array('DeleteBlock', 'ShowMsg'), 'block_id' => $iBlockId, 'msg' => _t('_sys_wiki_block_deleted'));
+        return ($sMsg = _t('_sys_wiki_block_deleted')) && $this->_bIsApi ? [bx_api_get_msg($sMsg, ['ext' => ['code' => 0, 'block_id' => $iBlockId]])] : [
+            'code' => 0, 
+            'actions' => ['DeleteBlock', 'ShowMsg'], 
+            'block_id' => $iBlockId, 
+            'msg' => $sMsg
+        ];
     }
-    public function actionHistory ()
+    public function actionHistory ($iBlockId = 0)
     {
-        $iBlockId = (int)bx_get('block_id');
+        if(!$iBlockId && ($_iBlockId = bx_get('block_id')) !== false)
+            $iBlockId = (int)$_iBlockId;
+
         $sLang = bx_lang_name();
         $oLang = BxDolLanguages::getInstance();
 
         $aVars = $this->getVarsForHistory($iBlockId, $sLang);
+
+        if($this->_bIsApi)
+            return ($aVersions = $aVars['bx_repeat:revisions'] ?: false) ? [bx_api_get_block('simple_list',  $aVersions)] : [bx_api_get_msg(_t('_sys_wiki_error_no_revs'), ['ext' => ['block_id' => $iBlockId]])];
+        
         $aVars['language'] = $oLang->getLangTitle($oLang->getLangId($sLang));
         $aVars['close'] = _t('_sys_close');
         $aVars['msg'] = $aVars['bx_repeat:revisions'] ? '' : _t('_sys_wiki_error_no_revs');
         return BxDolTemplate::getInstance()->parseHtmlByName('wiki_history.html', $aVars);
     }
 
-    public function actionTranslate ()
+    public function actionTranslate ($iBlockId = 0)
     {
-        return $this->actionEdit (true);
+        return $this->actionEdit ($iBlockId, true);
     }
 
-    public function actionEdit ($bTranslate = false)
+    public function actionEdit ($iBlockId = 0, $bTranslate = false)
     {
-        $iBlockId = (int)bx_get('block_id');
+        if(!$iBlockId && ($_iBlockId = bx_get('block_id')) !== false)
+            $iBlockId = (int)$_iBlockId;
+
         $sMainLangLabel = '';
         $aWikiVerMain = array();
         $sLangForTranslate = '';
@@ -639,10 +677,10 @@ class BxDolWiki extends BxDolFactory implements iBxDolFactoryObject
 
         // don't allow to translate empty blocks
         if (!$aWikiVerMain && $bTranslate)
-            return BxDolTemplate::getInstance()->parseHtmlByName('wiki_msg.html', array(
+            return ($sMsg = _t('_sys_wiki_error_no_revs')) && $this->_bIsApi ? [bx_api_get_msg($sMsg)] : BxDolTemplate::getInstance()->parseHtmlByName('wiki_msg.html', [
                 'close' => _t('_sys_close'),
-                'msg' => _t('_sys_wiki_error_no_revs'),
-            ));
+                'msg' => $sMsg,
+            ]);
 
         // get latest revision for block with current lang
         if ($bTranslate) {
@@ -666,7 +704,7 @@ class BxDolWiki extends BxDolFactory implements iBxDolFactoryObject
         // init form object
         $oForm = BxDolForm::getObjectInstance('sys_wiki', $bTranslate ? 'sys_wiki_translate' : 'sys_wiki_edit');
         if (!$oForm)
-            return _t('_sys_wiki_error_occured', 12);
+            return ($sMsg = _t('_sys_wiki_error_occured', 12)) && $this->_bIsApi ? [bx_api_get_msg($sMsg)] : $sMsg;
 
         if (isset($oForm->aInputs['language']))
             $oForm->aInputs['language']['values'] = $aLangsForInput;
@@ -678,13 +716,18 @@ class BxDolWiki extends BxDolFactory implements iBxDolFactoryObject
         $oForm->initChecker($aWikiVer);
         if (!$oForm->isSubmittedAndValid()) {
             // display form
-            return BxDolTemplate::getInstance()->parseHtmlByName('wiki_form.html', array(
+            return $this->_bIsApi ? [bx_api_get_block('form', $oForm->getCodeAPI(), [
+                'ext' => [
+                    'name' => $this->_sObject, 
+                    'request' => ['url' => '/api.php?r=system/wiki_action/TemplServiceWiki&params[]=' . $this->getUri() . '&params[]=' . ($bTranslate ? 'translate' : 'edit') . '&params[]=' . $iBlockId, 'immutable' => true]
+                ]
+            ])] : BxDolTemplate::getInstance()->parseHtmlByName('wiki_form.html', [
                 'form' => $oForm->getCode(),
                 'block_id' => $iBlockId,
                 'wiki_action_uri' => $this->getUri(),
                 'action' => $bTranslate ? 'translate' : 'edit',
                 'txt_open_editor' => bx_js_string(_t('_sys_wiki_open_in_editor')),
-            ));
+            ]);
         } 
         else {
             $sLang = $oForm->getCleanValue('language');
@@ -739,7 +782,7 @@ class BxDolWiki extends BxDolFactory implements iBxDolFactoryObject
             // update indexing data
             $this->updateBlockIndexingData($iBlockId);
 
-            return array('code' => 0, 'actions' => array('Reload', 'ClosePopup'), 'block_id' => $iBlockId);
+            return $this->_bIsApi ? ['code' => 0, 'block_id' => $iBlockId] : ['code' => 0, 'actions' => ['Reload', 'ClosePopup'], 'block_id' => $iBlockId];
         }
     }
 
@@ -863,21 +906,36 @@ class BxDolWiki extends BxDolFactory implements iBxDolFactoryObject
 
     public function getVarsForHistory ($iBlockId, $sLang)
     {
+        $sUrl = '';
+        if(!($aPage = $this->_oQuery->getPageByBlockId($iBlockId))) {
+            list($sPageLink, $aPageParams) = bx_get_base_url_popup();
+            $sUrl = bx_absolute_url(BxDolPermalinks::getInstance()->permalink(bx_append_url_params($sPageLink, $aPageParams)));
+        }
+        else
+            $sUrl = $this->getPageUrl($aPage['uri']);
+
         $a = $this->_oQuery->getBlockHistory($iBlockId, $sLang);
 
-        $aVars = array(
-            'bx_repeat:revisions' => array()
-        );
+        $aVars = [];
         foreach ($a as $r) {
             $oProfile = BxDolProfile::getInstanceMagic($r['profile_id']);
-            list($sPageLink, $aPageParams) = bx_get_base_url_popup(array($r['block_id'].'rev' => $r['revision']));
-            $r['author_url'] = $oProfile->getUrl();
-            $r['author_name'] = $oProfile->getDisplayName();
-            $r['timejs'] = bx_time_js($r['added']);
-            $r['rev_url'] = BxDolPermalinks::getInstance()->permalink(bx_append_url_params($sPageLink, $aPageParams));
-            $aVars['bx_repeat:revisions'][] = $r;
+
+            $sUrlRef = bx_append_url_params($sUrl, [$r['block_id'] . 'rev' => $r['revision']]);
+
+            $aVars[] = array_merge($r, $this->_bIsApi ? [
+                'author_data' => BxDolProfile::getData($oProfile),
+                'rev_url' => bx_api_get_relative_url($sUrlRef)
+            ] : [
+                'author_name' => $oProfile->getDisplayName(),
+                'author_url' => $oProfile->getUrl(),
+                'timejs' => bx_time_js($r['added']),
+                'rev_url' => $sUrlRef
+            ]);
         }
-        return $aVars;
+
+        return [
+            'bx_repeat:revisions' => $aVars
+        ];
     }
 }
 

+ 1 - 0
install/sql/app-pages.sql

@@ -53,6 +53,7 @@ UPDATE `sys_pages_blocks` SET `active_api`=1 WHERE `object`='sys_unsubscribe_new
 UPDATE `sys_pages_blocks` SET `active_api`=1 WHERE `object`='sys_cmts_administration' AND `module`='system' AND `title_system`='_sys_page_block_title_system_cmts_administration' AND `title`='_sys_page_block_title_cmts_administration';
 UPDATE `sys_pages_blocks` SET `active_api`=1 WHERE `object`='sys_redirect' AND `module`='system' AND `title_system`='' AND `title`='_sys_page_block_title_redirect';
 UPDATE `sys_pages_blocks` SET `active_api`=1 WHERE `object`='sys_search_keyword' AND `module`='system' AND `title_system`='' AND `title`='_sys_page_block_title_search_keyword_result';
+UPDATE `sys_pages_blocks` SET `active_api`=1 WHERE `object`='sys_wiki_add_page' AND `module`='system' AND `title_system`='' AND `title`='_sys_page_block_title_wiki_add_page';
 UPDATE `sys_pages_blocks` SET `active_api`=1 WHERE `object`='sys_sub_wiki_page_contents' AND `module`='system' AND `title_system`='' AND `title`='_sys_page_block_title_wiki_page_contents';
 UPDATE `sys_pages_blocks` SET `active_api`=1 WHERE `object`='sys_std_dashboard' AND `module`='system' AND `title_system`='' AND `title`='_sys_page_block_title_std_dash_version';
 UPDATE `sys_pages_blocks` SET `active_api`=1 WHERE `object`='sys_std_dashboard' AND `module`='system' AND `title_system`='' AND `title`='_sys_page_block_title_std_dash_space';

+ 3 - 1
install/sql/system.sql

@@ -6217,7 +6217,8 @@ INSERT INTO `sys_objects_page` (`object`, `uri`, `title_system`, `title`, `modul
 ('sys_audit' ,'audit-administration', '_sys_page_title_system_audit_administration', '_sys_page_title_audit_administration', 'system', 1, 5, '', 192, 1, 'page.php?i=audit-administration', '', '', '', 0, 1, 0, '', '', 0),
 ('sys_search_keyword', 'search-keyword', '_sys_page_title_system_search_keyword', '_sys_page_title_search_keyword', 'system', 1, 5, '', 2147483647, 1, 'searchKeyword.php', '', '', '', 0, 1, 0, '', '', 0),
 ('sys_redirect', 'redirect', '', '_sys_page_title_redirect', 'system', 0, 18, '', 2147483647, 1, 'page.php?i=redirect', '', '', '', 0, 1, 0, '', '', 0),
-('sys_sub_wiki_pages_list', 'wiki-pages-list', '', '_sys_page_title_wiki_pages_list', 'system', 1, 5, '', 2147483647, 1, '', '', '', '', 0, 1, 0, '', '', 0),
+('sys_wiki_add_page', 'wiki-add-page', '', '_sys_page_title_wiki_add_page', 'system', 1, 5, '', 2147483647, 1, 'page.php?i=wiki-add-page', '', '', '', 0, 1, 0, '', '', 0),
+('sys_sub_wiki_pages_list', 'wiki-pages-list', '_sys_page_title_sys_wiki_pages_list', '_sys_page_title_wiki_pages_list', 'system', 1, 5, '', 2147483647, 1, '', '', '', '', 0, 1, 0, '', '', 0),
 ('sys_sub_wiki_page_contents', 'wiki-page-contents', '', '_sys_page_title_wiki_page_contents', 'system', 1, 5, '', 2147483647, 1, '', '', '', '', 0, 1, 0, '', '', 0),
 ('sys_con_friends', 'friends', '_sys_page_title_system_con_friends', '_sys_page_title_con_friends', 'system', 1, 5, '', 2147483646, 1, 'page.php?i=friends', '', '', '', 0, 1, 0, 'BxTemplPageConnections', '', 0),
 ('sys_con_friend_requests', 'friend-requests', '_sys_page_title_system_con_friend_requests', '_sys_page_title_con_friend_requests', 'system', 1, 5, '', 2147483646, 1, 'page.php?i=friend-requests', '', '', '', 0, 1, 0, 'BxTemplPageConnections', '', 0),
@@ -6513,6 +6514,7 @@ INSERT INTO `sys_pages_blocks` (`object`, `cell_id`, `module`, `title_system`, `
 ('sys_search_keyword', 1, 'system', '', '_sys_page_block_title_search_keyword_form', 13, 0, 0, 2147483647, 'service', 'a:4:{s:6:"module";s:6:"system";s:6:"method";s:19:"search_keyword_form";s:6:"params";a:0:{}s:5:"class";s:13:"TemplServices";}', 0, 1, 1, 1),
 ('sys_search_keyword', 1, 'system', '', '_sys_page_block_title_search_keyword_result', 0, 0, 0, 2147483647, 'service', 'a:4:{s:6:"module";s:6:"system";s:6:"method";s:21:"search_keyword_result";s:6:"params";a:0:{}s:5:"class";s:13:"TemplServices";}', 0, 1, 1, 1),
 
+('sys_wiki_add_page', 1, 'system', '', '_sys_page_block_title_wiki_add_page', 0, 0, 0, 2147483647, 'service', 'a:4:{s:6:"module";s:6:"system";s:6:"method";s:13:"wiki_add_page";s:6:"params";a:2:{i:0;s:8:"{object}";i:1;s:5:"{uri}";}s:5:"class";s:16:"TemplServiceWiki";}', 0, 1, 1, 1),
 ('sys_sub_wiki_pages_list', 1, 'system', '', '_sys_page_block_title_wiki_pages_list', 0, 0, 0, 2147483647, 'service', 'a:4:{s:6:"module";s:6:"system";s:6:"method";s:10:"pages_list";s:6:"params";a:0:{}s:5:"class";s:16:"TemplServiceWiki";}', 0, 1, 1, 1),
 ('sys_sub_wiki_page_contents', 1, 'system', '', '_sys_page_block_title_wiki_page_contents', 0, 0, 0, 2147483647, 'service', 'a:4:{s:6:"module";s:6:"system";s:6:"method";s:13:"page_contents";s:6:"params";a:0:{}s:5:"class";s:16:"TemplServiceWiki";}', 0, 1, 1, 1),
 

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

@@ -3960,6 +3960,9 @@ If it is not enabled then please consider implement this optimization, since it
     <string name="_sys_page_title_unsubscribe_news"><![CDATA[Unsubscribe From Site Newsletters]]></string>
     <string name="_sys_page_title_unsubscribe_notifications"><![CDATA[Unsubscribe From Site Notifications]]></string>
     <string name="_sys_page_title_studio_dashboard"><![CDATA[Studio Dashboard]]></string>
+    <string name="_sys_page_title_sys_wiki_pages_list"><![CDATA[Wiki: Add Page]]></string>
+    <string name="_sys_page_title_wiki_add_page"><![CDATA[Add Page]]></string>
+    <string name="_sys_page_block_title_wiki_add_page"><![CDATA[Add Page]]></string>
     <string name="_sys_page_title_wiki_pages_list"><![CDATA[Subpage: Pages List]]></string>
     <string name="_sys_page_title_wiki_page_contents"><![CDATA[Subpage: Page Contents]]></string>
     <string name="_sys_page_title_system_con_friends"><![CDATA[Connections - Friends]]></string>

+ 4 - 1
modules/boonex/russian/data/langs/system/ru.xml

@@ -3918,7 +3918,10 @@
 	<string name="_sys_page_title_unsubscribe_news"><![CDATA[Отписаться от новостей сайта]]></string>
 	<string name="_sys_page_title_unsubscribe_notifications"><![CDATA[Отписаться от уведомлений сайта]]></string>
 	<string name="_sys_page_title_studio_dashboard"><![CDATA[Студия - Панель]]></string>
-	<string name="_sys_page_title_wiki_pages_list"><![CDATA[Подстраница: Список страниц]]></string>
+        <string name="_sys_page_title_sys_wiki_pages_list"><![CDATA[Вики: Добавить страницу]]></string>
+        <string name="_sys_page_title_wiki_add_page"><![CDATA[Добавить страницу]]></string>
+        <string name="_sys_page_block_title_wiki_add_page"><![CDATA[Добавить страницу]]></string>
+        <string name="_sys_page_title_wiki_pages_list"><![CDATA[Подстраница: Список страниц]]></string>
 	<string name="_sys_page_title_wiki_page_contents"><![CDATA[Подстраница: Содержание страницы]]></string>
         <string name="_sys_page_title_system_con_friends"><![CDATA[Связи - Друзья]]></string>
         <string name="_sys_page_title_con_friends"><![CDATA[Друзья]]></string>

+ 93 - 7
template/scripts/BxBaseMenuWiki.php

@@ -18,13 +18,19 @@ class BxBaseMenuWiki extends BxTemplMenu
     public function __construct ($aObject, $oTemplate)
     {
         parent::__construct ($aObject, $oTemplate);
-        if ($sWikiObj = bx_get('wiki_obj')) {
-            $oWiki = BxDolWiki::getObjectInstance($sWikiObj);
-            if ($oWiki) {
-                $this->_oWikiObject = $oWiki;
-                $this->_iBlockId = (int)bx_get('block_id');
-            }
-        }
+
+        if(($sObject = bx_get('wiki_obj')) !== false)
+            $this->setParams($sObject, bx_get('block_id'));
+    }
+
+    public function setParams($sObject, $iBlockId)
+    {
+        $oObject = BxDolWiki::getObjectInstance($sObject);
+        if(!$oObject)
+            return;
+
+        $this->_oWikiObject = $oObject;
+        $this->_iBlockId = (int)$iBlockId;
     }
 
     public function getCode ()
@@ -34,6 +40,86 @@ class BxBaseMenuWiki extends BxTemplMenu
         return $s;
     }
 
+    protected function _getMenuItemEditImage($aItem)
+    {
+        $CNF = &$this->_oModule->_oConfig->CNF;
+
+        $aResult = $this->_getMenuItemByNameActions($aItem, [
+            'object_menu' => $CNF['OBJECT_MENU_ACTIONS_VIEW_MEDIA']
+        ]);
+
+        if($this->_bIsApi) {
+            $aResult = array_merge($aResult, [
+                'link' => BxDolPermalinks::getInstance()->permalink('page.php?i=' . $CNF['URI_EDIT_MEDIA'] . '&id=' . $this->_iMediaId),
+            ]);
+
+            unset($aResult['display_type'], $aResult['data']);
+        }
+
+        return $aResult;
+    }
+
+    protected function _getMenuItemAPI($a)
+    {
+        $aResult = parent::_getMenuItemAPI($a);
+        
+        $sUri = $this->_oWikiObject->getUri();
+        
+        $aAdd = [];
+        switch($a['name']) {
+            case 'edit':
+                $aAdd = [
+                    'display_type' => 'modal',
+                    'data' => [
+                        'request_url' => 'system/wiki_action/TemplServiceWiki&params[]=' . $sUri . '&params[]=edit&params[]=' . $this->_iBlockId,
+                    ]
+                ];
+                break;
+
+            case 'delete-version':
+                $aAdd = [
+                    'display_type' => 'modal',
+                    'data' => [
+                        'request_url' => 'system/wiki_action/TemplServiceWiki&params[]=' . $sUri . '&params[]=delete-version&params[]=' . $this->_iBlockId,
+                    ]
+                ];
+                break;
+
+            case 'delete-block':
+                $aAdd = [
+                    'display_type' => 'callback',
+                    'data' => [
+                        'request_url' => 'system/wiki_action/TemplServiceWiki&params[]=' . $sUri . '&params[]=delete-block&params[]=' . $this->_iBlockId,
+                        'on_callback' => 'hide'
+                    ]
+                ];
+                break;
+
+            case 'translate':
+                $aAdd = [
+                    'display_type' => 'modal',
+                    'data' => [
+                        'request_url' => 'system/wiki_action/TemplServiceWiki&params[]=' . $sUri . '&params[]=translate&params[]=' . $this->_iBlockId,
+                    ]
+                ];
+                break;
+
+            case 'history':
+                $aAdd = [
+                    'display_type' => 'modal',
+                    'data' => [
+                        'request_url' => 'system/wiki_action/TemplServiceWiki&params[]=' . $sUri . '&params[]=history&params[]=' . $this->_iBlockId,
+                    ]
+                ];
+                break;
+        }
+
+        if($aAdd)
+            $aResult = array_merge($aResult, $aAdd);
+
+        return $aResult;
+    }
+
     /**
      * Check if menu items is visible with extended checking for friends notifications
      * @param $a menu item array

+ 7 - 4
template/scripts/BxBasePage.php

@@ -1292,14 +1292,17 @@ class BxBasePage extends BxDolPage
     {
         $oWiki = BxDolWiki::getObjectInstance($this->_aObject['module']);
         if (!$oWiki) {
-            $sContent = _t('_sys_wiki_error_missing_wiki_object', $this->_aObject['module']);
+            $sContent = ($sMsg = _t('_sys_wiki_error_missing_wiki_object', $this->_aObject['module'])) && $this->_bIsApi ? ['content' => $sMsg] : $sMsg;
         } 
         else {
-            $sContent = $oWiki->getBlockContent($aBlock['id'], false, (int)bx_get($aBlock['id'].'rev') ? (int)bx_get($aBlock['id'].'rev') : false);
+            $sContent = $oWiki->getBlockContent($aBlock['id'], false, ($iRevision = bx_get($aBlock['id'] . 'rev')) !== false ? (int)$iRevision : false);
         }
 
-        if(bx_is_api())
-            return [bx_api_get_block('html', ['title' => _t($aBlock['title']), 'content' => $sContent])];
+        if($this->_bIsApi)
+            return [bx_api_get_block('html', array_merge([
+                'title' => _t($aBlock['title']), 
+                'content' => ''
+            ], $sContent))];
 
         $s = '<div id="bx-page-wiki-container-' . $aBlock['id'] . '" class="bx-page-wiki-container markdown-body bx-def-vanilla-html">' . $sContent . '</div>';
         $s = $this->_replaceMarkers($s, array('block_id' => $aBlock['id']));

+ 7 - 0
template/scripts/BxBasePageWiki.php

@@ -25,6 +25,13 @@ class BxBasePageWiki extends BxTemplPage
         if($aPagesList && ($aCell = $aPagesList['elements']['cell_center'] ?? false))
             $aPage['elements']['cell_left'] = $aCell;
 
+        $sCell = 'center';
+        if(($oWiki = BxDolWiki::getObjectInstance($this->_aObject['module'])) && $oWiki->isAllowed('add')) {
+            $aLayoutColumns = $this->_oQuery->getPageLayoutColumns($this->_aObject['layout_id'], 'name');
+
+            $aPage['elements']['cell_' . $sCell][] = bx_srv('system', 'wiki_add_block', [$oWiki, $this->_sObject, 'cell_' . $aLayoutColumns[$sCell]['index']], 'TemplServiceWiki');
+        }
+
         return $aPage;
     }
 

+ 6 - 19
template/scripts/BxBaseServicePages.php

@@ -157,33 +157,20 @@ class BxBaseServicePages extends BxDol
     {
         $mixed = null;
 
-        if (substr_count($sRequest, 'page/')> 0){
-            $_GET['i'] = str_replace('page/', '', $sRequest);
+        if(($sK = 'page') && substr_count($sRequest, $sK . '/') > 0) {
+            $_GET['i'] = str_replace($sK . '/', '', $sRequest);
             $aParams = json_decode($sParams, true);
             if(!empty($aParams) && is_array($aParams))
                 $_GET = array_merge($_GET, $aParams);
-            
+
             $mixed = BxDolPage::getObjectInstanceByURI();
         }
-        else if (($sK = 'wiki') && substr_count($sRequest, $sK . '/') > 0) {
+        else if(($sK = 'wiki') && substr_count($sRequest, $sK . '/') > 0) {
             $sUri = str_replace($sK . '/', '', $sRequest);
 
-            if(($oWiki = BxDolWiki::getObjectInstanceByUri($sK)) !== false) {
-                $oPage = BxDolPage::getObjectInstanceByModuleAndURI($oWiki->getObjectName(), $sUri);
-                if($oPage !== false) {
-                    $_GET['i'] = $sUri;
-                    
-                    /*
-                    $aParams = json_decode($sParams, true);
-                    if(!empty($aParams) && is_array($aParams))
-                        $_GET = array_merge($_GET, $aParams);
-                    */
-                    
-                    $mixed = $oPage;
-                }
-            }
+            $mixed = bx_srv('system', 'wiki_page', [$sK, $sUri], 'TemplServiceWiki');
         }
-        else{
+        else {
             if(!empty($sParams)) {
                 $aParams = json_decode($sParams, true);
                 if(!empty($aParams) && is_array($aParams))

+ 179 - 68
template/scripts/BxBaseServiceWiki.php

@@ -12,8 +12,16 @@
  */
 class BxBaseServiceWiki extends BxDol
 {
+    protected $_bIsApi;
     protected $_bJsCssAdded = false;
 
+    public function __construct()
+    {
+        parent::__construct();
+
+        $this->_bIsApi = bx_is_api();
+    }
+    
     /**
      * @page service Service Calls
      * @section bx_system_general System Services 
@@ -34,46 +42,100 @@ class BxBaseServiceWiki extends BxDol
     public function serviceWikiPage ($sWikiObjectUri, $sUri)
     {
         $oWiki = BxDolWiki::getObjectInstanceByUri($sWikiObjectUri);
-        if (!$oWiki) {
-            $oTemplate = BxDolTemplate::getInstance();
-            $oTemplate->displayPageNotFound();
-            return;
+        if(!$oWiki) {
+            if($this->_bIsApi)
+                return null;
+
+            BxDolTemplate::getInstance()->displayPageNotFound();
         }
 
         $oPage = BxDolPage::getObjectInstanceByModuleAndURI($oWiki->getObjectName(), $sUri);
-        if ($oPage) {
-
+        if($oPage) {
             $_GET['i'] = $sUri;
 
+            if($this->_bIsApi)
+                return $oPage;
+
             $oPage->displayPage();
+        } 
+        else {
+            if($oWiki->isAllowed('add-page')) {
+                if(($oPage = BxDolPage::getObjectInstanceByURI($sUri)) !== false) {
+                    if($this->_bIsApi) {
+                        $aPage = $oPage->getObject();
+                        if(($sUrl = $aPage['url'] ?? false))
+                            return bx_api_get_relative_url(BX_DOL_URL_ROOT . BxDolPermalinks::getInstance()->permalink($aPage['url']));
+                        else
+                            return null;
+                    }
+
+                    BxDolTemplate::getInstance()->displayErrorOccured(_t("_sys_wiki_error_page_exists", bx_process_output($sUri)));
+                } 
+                else {
+                    $oPage = BxDolPage::getObjectInstance('sys_wiki_add_page');
+                    if(!$oPage)
+                        return $this->_bIsApi ? null : BxDolTemplate::getInstance()->displayPageNotFound();
 
-        } else {
-
-            if ($oWiki->isAllowed('add-page')) {
-                $oPage = BxDolPage::getObjectInstanceByURI($sUri);
-                $oTemplate = BxDolTemplate::getInstance();
-                if ($oPage) {                    
-                    $oTemplate->displayErrorOccured(_t("_sys_wiki_error_page_exists", bx_process_output($sUri)));
-                } else {
-                    $this->_addCssJs (true);
-                    $s = $oTemplate->parseHtmlByName('wiki_create_page.html', array(
-                        'page_uri' => bx_process_output($sUri),
-                        'action_uri' => $oWiki->getUri(),
-                        'create_page' => _t('_sys_wiki_add_page'),
-                        'text' => _t('_sys_wiki_add_page_text'),
-                    ));
-                    $oTemplate->setPageNameIndex (BX_PAGE_DEFAULT);
-                    $oTemplate->setPageHeader (_t('_sys_wiki_add_page'));
-                    $oTemplate->setPageContent ('page_main_code', $s);
-                    $oTemplate->getPageCode();
+                    $oPage->addMarkers([
+                        'object' => $oWiki->getObjectName(),
+                        'uri' => $sUri
+                    ]);
+
+                    if($this->_bIsApi)
+                        return $oPage;
+
+                    $this->_addCssJs(true);
+                    $oPage->displayPage();
                 }
-            } 
+            }
             else {
-                $oTemplate = BxDolTemplate::getInstance();
-                $oTemplate->displayPageNotFound();
+                if($this->_bIsApi)
+                    return null;
+
+                BxDolTemplate::getInstance()->displayPageNotFound();
             }
         }
+    }
 
+    /**
+     * @page service Service Calls
+     * @section bx_system_general System Services 
+     * @subsection bx_system_general-wiki Wiki
+     * @subsubsection bx_system_general-wiki_add_page wiki_add_page
+     * 
+     * @code bx_srv('system', 'wiki_add_page', [...], 'TemplServiceWiki'); @endcode
+     * 
+     * Display add WIKI page.
+     * @param $sObject wiki object name
+     * @param $sUri new page URI
+     * 
+     * @see BxBaseServiceWiki::serviceWikiAddPage
+     */
+    /** 
+     * @ref bx_system_general-wiki_add_page "wiki_add_page"
+     */
+    public function serviceWikiAddPage ($sObject, $sUri)
+    {
+        $oWiki = BxDolWiki::getObjectInstance($sObject);
+        if(!$oWiki)
+            return $this->_bIsApi ? [] : '';
+
+        $sTitle = _t('_sys_wiki_add_page');
+        $sText = _t('_sys_wiki_add_page_text');
+        
+        if($this->_bIsApi)
+            return [bx_api_get_block('wiki_add_page', [
+                'title' => $sTitle,
+                'text' => $sText,
+                'request_url' => 'system/wiki_action/TemplServiceWiki&params[]=' . $oWiki->getUri() . '&params[]=add-page&params[]=' . $sUri
+            ])];
+
+        return BxDolTemplate::getInstance()->parseHtmlByName('wiki_create_page.html', [
+            'page_uri' => bx_process_output($sUri),
+            'action_uri' => $oWiki->getUri(),
+            'create_page' => $sTitle,
+            'text' => $sText,
+        ]);
     }
 
     /**
@@ -95,19 +157,18 @@ class BxBaseServiceWiki extends BxDol
     public function serviceWikiAction ($sWikiObjectUri, $sAction)
     {
         $oWiki = BxDolWiki::getObjectInstanceByUri($sWikiObjectUri);
-        if (!$oWiki) {
-            echoJson(array('code' => 1, 'actions' => 'ShowMsg', 'msg' => _t('_sys_wiki_error_missing_wiki_object', $sWikiObjectUri)));
-            return;
-        }
+        if(!$oWiki)
+            return ($sMsg = _t('_sys_wiki_error_missing_wiki_object', $sWikiObjectUri)) && $this->_bIsApi ? [bx_api_get_msg($sMsg, ['ext' => ['code' => 1]])] : echoJson(['code' => 1, 'actions' => 'ShowMsg', 'msg' => $sMsg]);
 
         $sMethod = 'action' . bx_gen_method_name($sAction, array('-'));
-        if (!method_exists($oWiki, $sMethod) || !$oWiki->isAllowed($sAction)) {            
-            echoJson(array('code' => 2, 'actions' => 'ShowMsg', 'msg' => _t('_sys_wiki_error_action_not_allowed', $sAction, $sWikiObjectUri)));
-            return;
-        }
-        
-        $mixed = $oWiki->$sMethod();
-        if (is_array($mixed))
+        if(!method_exists($oWiki, $sMethod) || !$oWiki->isAllowed($sAction))
+            return ($sMsg = _t('_sys_wiki_error_action_not_allowed', $sAction, $sWikiObjectUri)) && $this->_bIsApi ? [bx_api_get_msg($sMsg, ['ext' => ['code' => 2]])] : echoJson(['code' => 2, 'actions' => 'ShowMsg', 'msg' => $sMsg]);
+
+        $mixed = call_user_func_array([$oWiki, $sMethod], array_slice(func_get_args(), 2));
+        if($this->_bIsApi)
+            return $mixed;
+
+        if(is_array($mixed))
             echoJson($mixed);
         else
             echo $mixed;
@@ -126,39 +187,64 @@ class BxBaseServiceWiki extends BxDol
     /** 
      * @ref bx_system_general-wiki_controls "wiki_controls"
      */
-    public function serviceWikiControls ($oWikiObject, $aWikiVer, $aWikiVerLatest, $sBlockId)
+    public function serviceWikiControls ($oWikiObject, $aWikiVer, $aWikiVerLatest, $iBlockId)
     {
-        $this->_addCssJs ();
-    
-        $sInfo = '';
-        if ($aWikiVer && $aWikiVerLatest['revision'] == $aWikiVer['revision']) {
-            $sInfo = bx_time_js($aWikiVer['added']);
+        $this->_addCssJs();
+
+        $sObject = $oWikiObject->getObjectName();
+        $bAllowedManage = $oWikiObject->isAllowed('history');
+
+        $mixedInfo = '';
+        if($aWikiVer && $aWikiVerLatest['revision'] == $aWikiVer['revision']) {
+            $mixedInfo = $this->_bIsApi ? [
+                'added' => $aWikiVer['added']
+            ] : bx_time_js($aWikiVer['added']);
         } 
-        elseif ($aWikiVer) {
+        else if($aWikiVer) {
             $oProfile = BxDolProfile::getInstanceMagic($aWikiVer['profile_id']);
-            $sInfo = _t('_sys_wiki_view_rev', $aWikiVer['revision'], $oProfile->getUrl(), $oProfile->getDisplayName(), bx_time_js($aWikiVer['added']));
+
+            $mixedInfo = $this->_bIsApi ? [
+                'revision' => $aWikiVer['revision'],
+                'author_data' => BxDolProfile::getData($aWikiVer['profile_id']),
+                'added' => $aWikiVer['added']
+            ] : _t('_sys_wiki_view_rev', $aWikiVer['revision'], $oProfile->getUrl(), $oProfile->getDisplayName(), bx_time_js($aWikiVer['added']));
+        }
+
+        if($this->_bIsApi) {
+            $mixedMenu = '';
+            if($bAllowedManage) {
+                $oMenu = BxTemplMenu::getObjectInstance('sys_wiki');
+                $oMenu->setParams($sObject, $iBlockId);
+
+                $mixedMenu = $oMenu->getCodeAPI();
+            }
+
+            return [
+                'info' => $mixedInfo,
+                'menu' => $mixedMenu
+            ];
         }
 
         $o = BxDolTemplate::getInstance();
         $o->addJs('stackedit.js/stackedit.min.js');
-        return $o->parseHtmlByName('wiki_controls.html', array(
-            'obj' => $oWikiObject->getObjectName(),
-            'block_id' => $sBlockId,
-            'info' => $sInfo,
-            'options' => json_encode(array(
-                'block_id' => $sBlockId,
+        return $o->parseHtmlByName('wiki_controls.html', [
+            'obj' => $sObject,
+            'block_id' => $iBlockId,
+            'info' => $mixedInfo,
+            'options' => json_encode([
+                'block_id' => $iBlockId,
                 'language' => isset($aWikiVer['language']) ? $aWikiVer['language'] : bx_lang_name(),
                 'wiki_action_uri' => $oWikiObject->getUri(),
                 't_confirm_block_deletion' => _t('_sys_wiki_confirm_block_deletion'),
-            )),
-            'bx_if:menu' => array(
-                'condition' => $oWikiObject->isAllowed('history'),
-                'content' => array(
-                    'obj' => $oWikiObject->getObjectName(),
-                    'block_id' => $sBlockId,
-                ),
-            ),
-        ));
+            ]),
+            'bx_if:menu' => [
+                'condition' => $bAllowedManage,
+                'content' => [
+                    'obj' => $sObject,
+                    'block_id' => $iBlockId,
+                ],
+            ],
+        ]);
     }
 
     /**
@@ -176,18 +262,43 @@ class BxBaseServiceWiki extends BxDol
      */
     public function serviceWikiAddBlock ($oWikiObject, $sPageObject, $sCellId)
     {
-        $this->_addCssJs ();
-        if (!preg_match("/cell_(\d+)/", $sCellId, $aMatches))
+        $this->_addCssJs();
+
+        $aMatches = [];
+        if(!preg_match("/cell_(\d+)/", $sCellId, $aMatches))
             return '';
+
         $iCellId = $aMatches[1];
+        $sTxtAddBlock = _t('_sys_wiki_add_block');
+
+        if($this->_bIsApi) {
+            $sUri = $oWikiObject->getUri();
+
+            return [
+                'id' => $sUri . '_add_block',
+                'module' => $oWikiObject->getModule(),
+                'title' => '',
+                'description' => '',
+                'icon' => '',
+                'designbox_id' => 0,
+                'hidden_on' => false,
+                'content' => [bx_api_get_block('wiki_add_block', [
+                    'title' => $sTxtAddBlock, 
+                    'request_url' => 'system/wiki_action/TemplServiceWiki&params[]=' . $sUri . '&params[]=add&params[]=' . $sPageObject . '&params[]=' . $iCellId
+                ])],
+                'content_empty' => '',
+                'config_api' => '',
+                'menu' => '',
+                'source' => 'system:block_' . $sUri . '_add_block'
+            ];
+        }
 
-        $o = BxDolTemplate::getInstance();        
-        return $o->parseHtmlByName('wiki_add_block.html', array(
-            'add_block' => _t('_sys_wiki_add_block'),
+        return BxDolTemplate::getInstance()->parseHtmlByName('wiki_add_block.html', [
+            'add_block' => $sTxtAddBlock,
             'page' => $sPageObject,
             'cell_id' => $iCellId,
             'action_uri' => $oWikiObject->getUri(),
-        ));
+        ]);
     }
 
     /**

+ 3 - 1
template/scripts/BxBaseServices.php

@@ -128,7 +128,9 @@ class BxBaseServices extends BxDol implements iBxDolProfileService
 
             'GetLabels' => 'BxBaseLabelsServices',
             'GetForm' => 'BxBaseSearchExtendedServices',
-            'GetResults' => 'BxBaseSearchExtendedServices'
+            'GetResults' => 'BxBaseSearchExtendedServices',
+
+            'WikiAction' => 'BxBaseServiceWiki'
         );
     }