BxElsModule.php 18 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490
  1. <?php defined('BX_DOL') or die('hack attempt');
  2. /**
  3. * Copyright (c) UNA, Inc - https://una.io
  4. * MIT License - https://opensource.org/licenses/MIT
  5. *
  6. * @defgroup ElasticSearch ElasticSearch
  7. * @ingroup UnaModules
  8. *
  9. * @{
  10. */
  11. class BxElsModule extends BxBaseModGeneralModule
  12. {
  13. protected $_oApi;
  14. function __construct(&$aModule)
  15. {
  16. parent::__construct($aModule);
  17. bx_import('Api', $aModule);
  18. $this->_oApi = new BxElsApi($this);
  19. }
  20. public function actionDeleteOldIndex()
  21. {
  22. if (!isAdmin()) {
  23. BxDolTemplate::getInstance()->displayAccessDenied();
  24. exit;
  25. }
  26. $mixed = $this->_oApi->api('/' . $this->_oConfig->getIndex(), array(), 'delete');
  27. echo '<pre>';
  28. if (null === $mixed)
  29. echo $this->_oApi->getErrorMsg();
  30. else
  31. var_dump($mixed);
  32. echo '</pre>';
  33. }
  34. public function actionDebug($sIndex = '')
  35. {
  36. if(empty($sIndex))
  37. $sIndex = $this->_oConfig->getIndex();
  38. // search all
  39. $mixed = $this->_oApi->api('/' . $sIndex . '@bx_posts/doc/_search?q=*');
  40. // $mixed = $this->_oApi->api('/testdata/_search', ['query' => ['match_all' => (object)[]]]);
  41. // search for the term
  42. // $mixed = $this->_oApi->api('/testdata/_search', ['query' => ['simple_query_string' => ['query' => 'palm']]]);
  43. // $mixed = $this->_oApi->api('/testdata/_search?q=palm');
  44. // search in a field
  45. // $mixed = $this->_oApi->api('/testdata/_search', ['query' => ['simple_query_string' => ['query' => 'palm', 'fields' => ['name']]]]);
  46. // compound searchs
  47. /*
  48. $mixed = $this->_oApi->api('/testdata/_search', array(
  49. 'query' => array(
  50. 'bool' => array(
  51. 'filter' => array(
  52. array('term' => array('featured' => '0')),
  53. array('term' => array('allow_view_to' => '3')),
  54. array(
  55. 'dis_max' => array(
  56. 'queries' => array(
  57. array('term' => array('title' => 'uupdd')),
  58. array('term' => array('text' => 'uupdd'))
  59. )
  60. ),
  61. )
  62. ),
  63. ))
  64. ));
  65. $mixed = $this->api('/testdata/_search', array(
  66. 'query' => array(
  67. 'dis_max' => array(
  68. 'queries' => array(
  69. array('simple_query_string' => array('query' => 'uupd')),
  70. array('term' => array('title' => 'uupdd')),
  71. array('term' => array('text' => 'uupdd')),
  72. array(
  73. 'bool' => array(
  74. 'filter' => array(
  75. array('term' => array('featured' => '0')),
  76. array('term' => array('allow_view_to' => '3')),
  77. )
  78. ),
  79. )
  80. ),
  81. ))
  82. ));
  83. */
  84. // delete index
  85. //$mixed = $this->_oApi->api('/' . $this->_oConfig->getIndex(), array(), 'delete');
  86. // delete indexed doc
  87. //$mixed = $this->_oApi->api('/' . $this->_oConfig->getIndex() . '/trees/23', [], 'delete');
  88. // get indexed doc
  89. // $mixed = $this->_oApi->api('/testdata/trees/23');
  90. // index a doc
  91. // $mixed = $this->_oApi->indexData('testdata', 'trees', 23, ['name' => 'apple tree', 'fruits' => 'apples']);
  92. // $mixed = $this->_oApi->indexData('testdata', 'trees', 24, ['name' => 'palm', 'fruits' => 'coconuts']);
  93. // get indexes
  94. // $mixed = $this->_oApi->api('/_cat/indices');
  95. // add index
  96. // $mixed = $this->_oApi->api('/testdata', [], 'PUT');
  97. // test
  98. //$mixed = $this->_oApi->api('/_cat/health');
  99. // mapping put
  100. //$mixed = $this->_oApi->api('/' . $sIndex . '/_mapping/bx_forum', array('properties' => array('featured' => array('type' => 'long'))));
  101. // mapping get
  102. //$mixed = $this->_oApi->api('/' . $sIndex . '/_mapping' . (!empty($sType) ? '/' . $sType : ''));
  103. echo '<pre>';
  104. if (null === $mixed)
  105. echo $this->_oApi->getErrorMsg();
  106. else
  107. var_dump($mixed);
  108. echo '</pre>';
  109. }
  110. public function serviceGetSafeServices()
  111. {
  112. return array (
  113. 'SearchSimple' => '',
  114. 'SearchExtended' => '',
  115. );
  116. }
  117. /**
  118. * @page service Service Calls
  119. * @section bx_elasticsearch ElasticSearch
  120. * @subsection bx_elasticsearch-other Other
  121. * @subsubsection bx_elasticsearch-is_configured is_configured
  122. *
  123. * @code bx_srv('bx_elasticsearch', 'is_configured', [...]); @endcode
  124. *
  125. * Checkes whether the module is correctly configured or not.
  126. *
  127. * @return boolean value determining where the module is configured or not.
  128. *
  129. * @see BxElsModule::serviceIsConfigured
  130. */
  131. /**
  132. * @ref bx_elasticsearch-is_configured "is_configured"
  133. */
  134. public function serviceIsConfigured()
  135. {
  136. $CNF = &$this->_oConfig->CNF;
  137. return isset($CNF['PARAM_API_URL']) && getParam($CNF['PARAM_API_URL']) != '';
  138. }
  139. /**
  140. * @page service Service Calls
  141. * @section bx_elasticsearch ElasticSearch
  142. * @subsection bx_elasticsearch-search Search
  143. * @subsubsection bx_elasticsearch-search_simple search_simple
  144. *
  145. * @code bx_srv('bx_elasticsearch', 'search_simple', [...]); @endcode
  146. *
  147. * Perform a simple search by term. Index and Type to search in can be specified.
  148. *
  149. * @param $sTerm string value with keyword to search for.
  150. * @param $sType (optional) if type is specified then the search will be performed in this type only.
  151. * @param $sIndex (optional) if index is specified then the search will be performed in this index only.
  152. * @return an array with search results.
  153. *
  154. * @see BxElsModule::serviceSearchSimple
  155. */
  156. /**
  157. * @ref bx_elasticsearch-search_simple "search_simple"
  158. */
  159. public function serviceSearchSimple($sTerm, $sType = '', $sIndex = '')
  160. {
  161. if(empty($sIndex))
  162. $sIndex = $this->_oConfig->getIndex();
  163. $mixedResult = $this->_oApi->searchSimple($sIndex, $sType, $sTerm);
  164. if(!$mixedResult || !is_array($mixedResult))
  165. return false;
  166. return $mixedResult['hits'];
  167. }
  168. /**
  169. * @page service Service Calls
  170. * @section bx_elasticsearch ElasticSearch
  171. * @subsection bx_elasticsearch-search Search
  172. * @subsubsection bx_elasticsearch-search_extended search_extended
  173. *
  174. * @code bx_srv('bx_elasticsearch', 'search_extended', [...]); @endcode
  175. *
  176. * Perform an extended search by provided conditions. Index and Type to search in can be specified.
  177. *
  178. * @param $aCondition an array with conditions to construct search request from.
  179. * @param $aSelection (optional) an array with custom condition.
  180. * @param $sType (optional) if type is specified then the search will be performed in this type only.
  181. * @param $sIndex (optional) if index is specified then the search will be performed in this index only.
  182. * @return an array with search results.
  183. *
  184. * Condition #1: keyword search
  185. * $aCondition = array('val' => 'test');
  186. *
  187. * Condition #2: `featured`='1'
  188. * $aCondition = array('fld' => 'featured', 'val' => 0);
  189. *
  190. * Condition #3: (`title`='test' OR `text`='test' OR (`featured`='1' AND `allow_view_to`='3'))
  191. * $aCondition = array('grp' => true, 'opr' => 'OR', 'cnds' => array(
  192. * array('fld' => 'title', 'val' => 'test'),
  193. * array('fld' => 'text', 'val' => 'test'),
  194. * array('grp' => true, 'opr' => 'AND', 'cnds' => array(
  195. * array('fld' => 'featured', 'val' => 1),
  196. * array('fld' => 'allow_view_to', 'val' => 3)
  197. * )),
  198. * array('simple_query_string' => array('query' => 'test')),
  199. * ));
  200. *
  201. * Condition #4: ((`title`='test' OR `text`='test') AND `featured`='1' AND `allow_view_to`='3')
  202. * $aCondition = array('grp' => true, 'opr' => 'AND', 'cnds' => array(
  203. * array('grp' => true, 'opr' => 'OR', 'cnds' => array(
  204. * array('fld' => 'title', 'val' => 'test'),
  205. * array('fld' => 'text', 'val' => 'test'),
  206. * )),
  207. * array('fld' => 'featured', 'val' => 0),
  208. * array('fld' => 'allow_view_to', 'val' => 3)
  209. * ));
  210. *
  211. * @see BxElsModule::serviceSearchExtended
  212. */
  213. /**
  214. * @ref bx_elasticsearch-search_extended "search_extended"
  215. */
  216. public function serviceSearchExtended($aCondition, $aSelection = array(), $sType = '', $sIndex = '')
  217. {
  218. if(empty($sIndex))
  219. $sIndex = $this->_oConfig->getIndex();
  220. $mixedResult = $this->_oApi->searchExtended($sIndex, $sType, $aCondition, $aSelection);
  221. if(!$mixedResult || !is_array($mixedResult))
  222. return false;
  223. return $mixedResult['hits'];
  224. }
  225. /**
  226. * @page service Service Calls
  227. * @section bx_elasticsearch ElasticSearch
  228. * @subsection bx_elasticsearch-manage Manage
  229. * @subsubsection bx_elasticsearch-get get
  230. *
  231. * @code bx_srv('bx_elasticsearch', 'get', [...]); @endcode
  232. *
  233. * Get item's data by content ID and type.
  234. *
  235. * @param $iContentId integer value with content ID.
  236. * @param $sType a string with content type.
  237. * @param $sIndex (optional) if index is specified then the item will be searched in this index only.
  238. * @return an array with item's data.
  239. *
  240. * @see BxElsModule::serviceGet
  241. */
  242. /**
  243. * @ref bx_elasticsearch-get "get"
  244. */
  245. public function serviceGet($iContentId, $sType, $sIndex = '')
  246. {
  247. if(empty($sIndex))
  248. $sIndex = $this->_oConfig->getIndex();
  249. return $this->_oApi->getData($sIndex, $sType, $iContentId);
  250. }
  251. /**
  252. * @page service Service Calls
  253. * @section bx_elasticsearch ElasticSearch
  254. * @subsection bx_elasticsearch-manage Manage
  255. * @subsubsection bx_elasticsearch-add add
  256. *
  257. * @code bx_srv('bx_elasticsearch', 'add', [...]); @endcode
  258. *
  259. * Add item to store in Elasticsearch.
  260. *
  261. * @param $iContentId integer value with content ID.
  262. * @param $mixedContentInfo mixed value with content info to store.
  263. * @param $sIndex (optional) if index is specified then the item will be stored in this index.
  264. * @return boolean value determining where the item was added or not.
  265. *
  266. * @see BxElsModule::serviceAdd
  267. */
  268. /**
  269. * @ref bx_elasticsearch-add "add"
  270. */
  271. public function serviceAdd($iContentId, $mixedContentInfo, $sIndex = '')
  272. {
  273. if(is_array($mixedContentInfo)) {
  274. $sMethod = 'getObjectInstanceByAlert' . bx_gen_method_name($mixedContentInfo['alert_type']);
  275. $mixedContentInfo = BxDolContentInfo::$sMethod($mixedContentInfo['unit'], $mixedContentInfo['action']);
  276. }
  277. if(!($mixedContentInfo instanceof BxDolContentInfo))
  278. return false;
  279. $CNF = &$this->_oConfig->CNF;
  280. if(empty($sIndex))
  281. $sIndex = $this->_oConfig->getIndex();
  282. $aInfo = array(
  283. $CNF['FIELD_AUTHOR'] => $mixedContentInfo->getContentAuthor($iContentId),
  284. $CNF['FIELD_ADDED'] => $mixedContentInfo->getContentDateAdded($iContentId),
  285. $CNF['FIELD_CHANGED'] => $mixedContentInfo->getContentDateChanged($iContentId),
  286. $CNF['FIELD_LINK'] => $mixedContentInfo->getContentLink($iContentId),
  287. $CNF['FIELD_TITLE'] => $mixedContentInfo->getContentTitle($iContentId),
  288. $CNF['FIELD_TEXT'] => $mixedContentInfo->getContentText($iContentId),
  289. );
  290. $aInfo = array_merge($aInfo, $mixedContentInfo->getContentInfo($iContentId));
  291. $mixedResult = $this->_oApi->indexData($sIndex, $mixedContentInfo->getName(), $iContentId, $this->_prepareToIndex($aInfo));
  292. if($mixedResult === null)
  293. return false;
  294. return $mixedResult['result'] == 'created';
  295. }
  296. /**
  297. * @page service Service Calls
  298. * @section bx_elasticsearch ElasticSearch
  299. * @subsection bx_elasticsearch-manage Manage
  300. * @subsubsection bx_elasticsearch-update update
  301. *
  302. * @code bx_srv('bx_elasticsearch', 'update', [...]); @endcode
  303. *
  304. * Update item in Elasticsearch storage.
  305. *
  306. * @param $iContentId integer value with content ID.
  307. * @param $mixedContentInfo mixed value with new content info.
  308. * @param $sIndex (optional) if index is specified then the item will be updated in this index.
  309. * @return boolean value determining where the item was updated or not.
  310. *
  311. * @see BxElsModule::serviceUpdate
  312. */
  313. /**
  314. * @ref bx_elasticsearch-update "update"
  315. */
  316. public function serviceUpdate($iContentId, $mixedContentInfo, $sIndex = '')
  317. {
  318. if(is_array($mixedContentInfo)) {
  319. $sMethod = 'getObjectInstanceByAlert' . bx_gen_method_name($mixedContentInfo['alert_type']);
  320. $mixedContentInfo = BxDolContentInfo::$sMethod($mixedContentInfo['unit'], $mixedContentInfo['action']);
  321. }
  322. if(!($mixedContentInfo instanceof BxDolContentInfo))
  323. return false;
  324. $CNF = &$this->_oConfig->CNF;
  325. if(empty($sIndex))
  326. $sIndex = $this->_oConfig->getIndex();
  327. $aInfo = array(
  328. $CNF['FIELD_AUTHOR'] => $mixedContentInfo->getContentAuthor($iContentId),
  329. $CNF['FIELD_ADDED'] => $mixedContentInfo->getContentDateAdded($iContentId),
  330. $CNF['FIELD_CHANGED'] => $mixedContentInfo->getContentDateChanged($iContentId),
  331. $CNF['FIELD_LINK'] => $mixedContentInfo->getContentLink($iContentId),
  332. $CNF['FIELD_TITLE'] => $mixedContentInfo->getContentTitle($iContentId),
  333. $CNF['FIELD_TEXT'] => $mixedContentInfo->getContentText($iContentId),
  334. );
  335. $aInfo = array_merge($aInfo, $mixedContentInfo->getContentInfo($iContentId));
  336. $mixedResult = $this->_oApi->updateData($sIndex, $mixedContentInfo->getName(), $iContentId, $this->_prepareToIndex($aInfo));
  337. if($mixedResult === null)
  338. return false;
  339. return $mixedResult['result'] == 'updated';
  340. }
  341. /**
  342. * @page service Service Calls
  343. * @section bx_elasticsearch ElasticSearch
  344. * @subsection bx_elasticsearch-manage Manage
  345. * @subsubsection bx_elasticsearch-delete delete
  346. *
  347. * @code bx_srv('bx_elasticsearch', 'delete', [...]); @endcode
  348. *
  349. * Delete item from Elasticsearch storage.
  350. *
  351. * @param $iContentId integer value with content ID.
  352. * @param $mixedContentInfo mixed value with content info which is needed during deletion.
  353. * @param $sIndex (optional) if index is specified then the item will be deleted from this index.
  354. * @return boolean value determining where the item was deleted or not.
  355. *
  356. * @see BxElsModule::serviceDelete
  357. */
  358. /**
  359. * @ref bx_elasticsearch-delete "delete"
  360. */
  361. public function serviceDelete($iContentId, $mixedContentInfo, $sIndex = '')
  362. {
  363. if(is_array($mixedContentInfo)) {
  364. $sMethod = 'getObjectInstanceByAlert' . bx_gen_method_name($mixedContentInfo['alert_type']);
  365. $mixedContentInfo = BxDolContentInfo::$sMethod($mixedContentInfo['unit'], $mixedContentInfo['action']);
  366. }
  367. if(!($mixedContentInfo instanceof BxDolContentInfo))
  368. return false;
  369. $CNF = &$this->_oConfig->CNF;
  370. if(empty($sIndex))
  371. $sIndex = $this->_oConfig->getIndex();
  372. $mixedResult = $this->_oApi->deleteData($sIndex, $mixedContentInfo->getName(), $iContentId);
  373. if($mixedResult === null)
  374. return false;
  375. return $mixedResult['result'] == 'deleted';
  376. }
  377. /**
  378. * @page service Service Calls
  379. * @section bx_elasticsearch ElasticSearch
  380. * @subsection bx_elasticsearch-manage Manage
  381. * @subsubsection bx_elasticsearch-index index
  382. *
  383. * @code bx_srv('bx_elasticsearch', 'delete', [...]); @endcode
  384. *
  385. * Index data in Elasticsearch storage.
  386. *
  387. * @param $sIndex string value with storage's index name which will be indexed.
  388. * @param $sType (optional) if type is specified then data in this type will be indexed only.
  389. * @return boolean value determining where the data was indexed or not.
  390. *
  391. * @see BxElsModule::serviceIndex
  392. */
  393. /**
  394. * @ref bx_elasticsearch-index "index"
  395. */
  396. public function serviceIndex($sIndex, $sType = '')
  397. {
  398. if(empty($sIndex))
  399. $sIndex = $this->_oConfig->getIndex();
  400. $aTypes = !empty($sType) ? array($sType) : array_keys(BxDolContentInfo::getSystems());
  401. if(empty($aTypes) || !is_array($aTypes))
  402. return false;
  403. foreach($aTypes as $sType) {
  404. $oContentInfo = BxDolContentInfo::getObjectInstance($sType);
  405. if(!$oContentInfo)
  406. continue;
  407. $aIds = $oContentInfo->getAll(array('type' => 'all_ids'));
  408. if(empty($aIds) || !is_array($aIds))
  409. continue;
  410. foreach($aIds as $iId)
  411. $this->serviceAdd($iId, $oContentInfo);
  412. $sClassKey = 'BxDolContentInfo!' . $sType;
  413. unset($GLOBALS['bxDolClasses'][$sClassKey]);
  414. }
  415. return true;
  416. }
  417. protected function _prepareToIndex($mixed)
  418. {
  419. if(!is_array($mixed))
  420. return strip_tags($mixed);
  421. foreach($mixed as $mixedKey => $mixedValue)
  422. $mixed[$mixedKey] = strip_tags($mixedValue);
  423. return $mixed;
  424. }
  425. }
  426. /** @} */