| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361 |
- <?php defined('BX_DOL') or die('hack attempt');
- /**
- * Copyright (c) UNA, Inc - https://una.io
- * MIT License - https://opensource.org/licenses/MIT
- *
- * @defgroup Wiki Wiki
- * @ingroup UnaModules
- *
- * @{
- */
- class BxWikiStudioPage extends BxTemplStudioModule
- {
- function __construct($sModule, $mixedPageName, $sPage = "")
- {
- parent::__construct($sModule, $mixedPageName, $sPage);
- $this->aMenuItems = array(
- 'settings' => ['name' => 'settings', 'icon' => 'cogs', 'title' => '_adm_lmi_cpt_settings'],
- 'import' => ['name' => 'import', 'icon' => 'download', 'title' => '_bx_wiki_import'],
- );
- }
- function getImport ()
- {
- $aForm = array(
- 'form_attrs' => array(
- 'name' => 'bx-wiki-import',
- 'method' => 'post',
- ),
- 'params' => array(
- 'db' => array(
- 'submit_name' => 'do_submit',
- ),
- ),
- 'inputs' => array(
- 'repo' => array(
- 'type' => 'text',
- 'name' => 'repo',
- 'caption' => _t('_bx_wiki_repository_url'),
- 'required' => true,
- ),
- 'base_url' => array(
- 'type' => 'text',
- 'name' => 'base_url',
- 'caption' => _t('_bx_wiki_base_url'),
- 'required' => true,
- ),
- 'lang' => array(
- 'type' => 'select',
- 'name' => 'lang',
- 'caption' => _t('_bx_wiki_lang'),
- 'values' => BxDolLanguages::getInstance()->getLanguages(),
- 'value' => BxDolLanguages::getInstance()->getCurrentLanguage(),
- ),
- 'unsafe' => array(
- 'type' => 'checkbox',
- 'name' => 'unsafe',
- 'caption' => _t('_bx_wiki_unsafe'),
- ),
- 'add_titles' => array(
- 'type' => 'checkbox',
- 'name' => 'add_titles',
- 'caption' => _t('_bx_wiki_add_titles'),
- ),
- 'git' => array(
- 'type' => 'text',
- 'name' => 'git',
- 'caption' => _t('_bx_wiki_repository_git'),
- 'required' => true,
- 'value' => 'git',
- ),
- 'ext' => array(
- 'type' => 'text',
- 'name' => 'ext',
- 'caption' => _t('_bx_wiki_ext'),
- 'required' => true,
- 'value' => 'md',
- ),
- 'skip_files' => array(
- 'type' => 'textarea',
- 'name' => 'skip_files',
- 'caption' => _t('_bx_wiki_skip_files'),
- 'value' => '["_Footer.md"]',
- ),
- 'only_files' => array(
- 'type' => 'textarea',
- 'name' => 'only_files',
- 'caption' => _t('_bx_wiki_only_files'),
- ),
- 'page_uri_map' => array(
- 'type' => 'textarea',
- 'name' => 'page_uri_map',
- 'caption' => _t('_bx_wiki_page_uri_map'),
- 'value' => '{"Home": "Index", "Dashboard": "Wiki-Dashboard"}',
- ),
- 'submit' => array(
- 'type' => 'submit',
- 'name' => 'do_submit', // the same as key and database field name
- 'value' => _t('_bx_wiki_import'),
- ),
- ),
- );
- $oForm = new BxTemplFormView($aForm);
- $oForm->initChecker();
- if ($oForm->isSubmittedAndValid ()) {
- $sGit =
- $sRepoUrl =
- $aParams = [
- 'git' => $oForm->getCleanValue('git'),
- 'repository' => $oForm->getCleanValue('repo'),
- 'base_url' => $oForm->getCleanValue('base_url'),
- 'lang' => $oForm->getCleanValue('lang'),
- 'unsafe' => (bool)$oForm->getCleanValue('unsafe'),
- 'add_titles' => (bool)$oForm->getCleanValue('add_titles'),
- 'ext' => $oForm->getCleanValue('ext'),
- 'skip_files' => json_decode($oForm->getCleanValue('skip_files'), true),
- 'only_files' => json_decode($oForm->getCleanValue('only_files'), true),
- 'page_uri_map' => json_decode($oForm->getCleanValue('page_uri_map'), true),
- ];
- $sErrorMsg = '';
- $b = $this->import($aParams, $sErrorMsg);
- self::removeTmpFolder();
- if ($b)
- return _t('_bx_wiki_import_success');
- else
- return $sErrorMsg;
- }
- else {
- return $oForm->getCode();
- }
- }
- static public function import($aParams, &$sErrorMsg)
- {
- $sGit = $aParams['git'];
- $sRepoUrl = $aParams['repository'];
- $sExt = $aParams['ext'];
- $aSkipFiles = $aParams['skip_files'];
- $aOnlyFiles = $aParams['only_files'];
- $sErrorMsg = '';
- // empty directory to clone repository to
- $sDir = BX_DIRECTORY_PATH_TMP . 'bx_wiki_import';
- if (!self::removeTmpFolder()) {
- $sErrorMsg = "$sDir can't be removed";
- return false;
- }
- // clone repository
- $sCmd = "{$sGit} clone {$sRepoUrl} " . $sDir;
- $aOutput = null;
- $iRetVal = null;
- if (false === exec(escapeshellcmd($sCmd), $aOutput, $iRetVal) || (null !== $iRetVal && $iRetVal)) {
- $sErrorMsg = "Command($sCmd) execution failed: <pre>" . implode("\n", $aOutput) . "</pre>";
- return false;
- }
- if (false === ($h = opendir($sDir))) {
- $sErrorMsg = "Directory($sDir) read failed";
- return false;
- }
- // get list of files to import and check pages for existence
- $aFilesToImport = [];
- while (false !== ($sFile = readdir($h))) {
- if (!empty($aSkipFiles) && in_array($sFile, $aSkipFiles))
- continue;
- if (!empty($aOnlyFiles) && !in_array($sFile, $aOnlyFiles))
- continue;
- $a = pathinfo($sDir . '/' . $sFile);
- if (empty($a['filename']) || empty($a['extension']) || $a['extension'] != $sExt)
- continue;
- $sErrorMsgFile = '';
- if (self::isPageExist($aParams, $sDir . '/' . $sFile, $a['filename'], $sErrorMsgFile)) {
- $sErrorMsg = "File($sFile) import failed: $sErrorMsgFile";
- break;
- }
- $aFilesToImport[$sFile] = $a;
- }
- closedir($h);
- if ($sErrorMsg)
- return false;
- // perform import
- foreach ($aFilesToImport as $sFile => $a) {
- $sErrorMsgFile = '';
- if (!self::importFile($aParams, $sDir . '/' . $sFile, $a['filename'], $sErrorMsgFile)) {
- $sErrorMsg = "File($sFile) import failed: $sErrorMsgFile";
- break;
- }
- }
- if ($sErrorMsg)
- return false;
- return true;
- }
- static protected function isPageExist($aParams, $sPath, $sTitle, &$sErrorMsg)
- {
- $aMapPageUris = $aParams['page_uri_map'];
- $sUri = $sTitle;
- if (isset($aMapPageUris[$sUri]))
- $sUri = $aMapPageUris[$sUri];
- if ($oPage = BxDolPage::getObjectInstanceByURI($sUri)) {
- $sErrorMsg = "Page with such URI($sUri) already exists";
- return true;
- }
- return false;
- }
- static protected function importFile($aParams, $sPath, $sTitle, &$sErrorMsg)
- {
- $sBaseUrlOld = $aParams['base_url'];
- $sLang = $aParams['lang'];
- $bUnsafe = $aParams['unsafe'];
- $bAddTitles = $aParams['add_titles'];
- $aMapPageUris = $aParams['page_uri_map'];
- if (false === ($sContents = file_get_contents($sPath)) || empty($sContents)) {
- $sErrorMsg = "File($sPath) read failed";
- return false;
- }
- $oWiki = BxDolWiki::getObjectInstance('bx_wiki');
- $sUri = $sTitle;
- if (isset($aMapPageUris[$sUri]))
- $sUri = $aMapPageUris[$sUri];
- $sTitle = str_replace('-', ' ', $sTitle);
- if (!($iPageId = $oWiki->addPage($sUri, $sTitle))) {
- $sErrorMsg = "Page with URI($sUri) add failed";
- return false;
- }
-
- if (!($oPage = BxDolPage::getObjectInstanceByURI($sUri))) {
- $sErrorMsg = "Page with URI($sUri) wasn't found";
- return false;
- }
- $iDesignBox = getParam('bx_wiki_design_box');
- $aBlock = array(
- 'object' => $oPage->getName(),
- 'cell_id' => 1,
- 'module' => 'bx_wiki',
- 'title_system' => '',
- 'title' => '',
- 'designbox_id' => false === $iDesignBox ? 0 : $iDesignBox,
- 'visible_for_levels' => 2147483647,
- 'type' => 'wiki',
- 'deletable' => 1,
- 'copyable' => 0,
- 'active' => 1,
- );
- $oQueryPageBuilder = new BxDolStudioBuilderPageQuery();
- if (!($iBlockId = $oQueryPageBuilder->insertBlock($aBlock))) {
- $sErrorMsg = "Page(" . $oPage->getName() . ") block add failed";
- return false;
- }
- $sContents = self::processImages($sContents, $aMapPageUris, $sBaseUrlOld, $iBlockId);
- $sContents = self::processContents($sContents, $aMapPageUris, $sBaseUrlOld, $iBlockId);
- if ($bAddTitles)
- $sContents = "# $sTitle\n\n" . $sContents;
- $oForm = BxDolForm::getObjectInstance('sys_wiki', 'sys_wiki_edit');
- $sIdRevision = $oForm->insert(array(
- 'block_id' => $iBlockId,
- 'revision' => 1,
- 'language' => $sLang,
- 'main_lang' => 1,
- 'profile_id' => 0,
- 'content' => $sContents,
- 'unsafe' => $bUnsafe,
- 'notes' => 'Import',
- 'added' => time(),
- ));
- if (!$sIdRevision) {
- $sErrorMsg = "Revision add failed for block ($iBlockId)";
- return false;
- }
- $oWiki->updateBlockIndexingData($iBlockId);
- return true;
- }
- static protected function processContents($sContents, $aMapPageUris, $sBaseUrlOld, $iBlockId)
- {
- // strip base URL
- $sContents = preg_replace("/\(" . preg_quote($sBaseUrlOld, '/') . "([^\)]+)\)/", "[$1]", $sContents);
- // replace special constructions which don't work locally
- $sContents = preg_replace('/\[\[(.+?)\|(.+?)\]\]/', '[$1][$2]', $sContents);
- $sContents = preg_replace('/\[(.+?)\|(.+?)\]/', '[$1][$2]', $sContents);
- // replace old URIs with new ones
- foreach ($aMapPageUris as $sOldUri => $sNewUri)
- $sContents = str_replace("[$sOldUri]", "[$sNewUri]", $sContents);
- // convert links to the proper ones
- $sContents = preg_replace('/\[(.+?)\]\[(http:\/\/.+?)\]/', '[$1]($2)', $sContents);
- $sContents = preg_replace('/\[(.+?)\]\[(https:\/\/.+?)\]/', '[$1]($2)', $sContents);
- return $sContents;
- }
- static protected function processImages($sContents, $aMapPageUris, $sBaseUrlOld, $iBlockId)
- {
- // unify links to images
- $sContents = preg_replace('/\[\[(.+?)\|alt=(.+?)\]\]/', '', $sContents);
- // process images
- $sContents = preg_replace_callback('/\!\[(.+?)\]\((.+?)\)/', function ($aMatches) use ($sBaseUrlOld, $iBlockId) {
- if (empty($aMatches[2]))
- return $aMatches[0];
- // strip base Wiki URL
- $sImg = str_replace($sBaseUrlOld, "", $aMatches[2]);
- // skip external URLs
- if (0 === strncmp($sImg, 'http://', 7) || 0 === strncmp($sImg, 'https://', 8))
- return $aMatches[0];
- $sImgPath = BX_DIRECTORY_PATH_TMP . 'bx_wiki_import/' . ltrim($sImg, '/');
- if (!file_exists($sImgPath))
- return $aMatches[0];
- $oStorage = BxDolStorage::getObjectInstance('sys_wiki_files');
- if (!$oStorage)
- return $aMatches[0];
- if (!($iFileId = $oStorage->storeFileFromPath($sImgPath, false, 0, $iBlockId)))
- return $aMatches[0];
- if (!($aFile = $oStorage->getFile($iFileId)))
- return $aMatches[0];
- return "![{$aMatches[2]}](" . $oStorage->getObject() . "/" . $aFile['remote_id'] . ")";
-
- }, $sContents);
- return $sContents;
- }
- static public function removeTmpFolder()
- {
- $sDir = BX_DIRECTORY_PATH_TMP . 'bx_wiki_import';
- return !file_exists($sDir) || bx_rrmdir($sDir);
- }
- }
- /** @} */
|