/package/app/app/plugins/sphinx_search/lib/kSphinxSearchManager.php

https://github.com/richhl/kalturaCE · PHP · 203 lines · 132 code · 30 blank · 41 comment · 11 complexity · 562e6b7b440b45dc54c6ccffe864d36f MD5 · raw file

  1. <?php
  2. class kSphinxSearchManager implements kObjectUpdatedEventConsumer, kObjectAddedEventConsumer
  3. {
  4. const SPHINX_INDEX_NAME = 'kaltura';
  5. const SPHINX_MAX_RECORDS = 1000;
  6. /**
  7. * @param string $baseName
  8. * @return string
  9. */
  10. public static function getSphinxIndexName($baseName)
  11. {
  12. return self::SPHINX_INDEX_NAME . '_' . $baseName;
  13. }
  14. /**
  15. * @param BaseObject $object
  16. * @return bool true if should continue to the next consumer
  17. */
  18. public function objectUpdated(BaseObject $object)
  19. {
  20. if(!($object instanceof IIndexable))
  21. return true;
  22. $this->saveToSphinx($object);
  23. return true;
  24. }
  25. /**
  26. * @param BaseObject $object
  27. * @return bool true if should continue to the next consumer
  28. */
  29. public function objectAdded(BaseObject $object)
  30. {
  31. if(!($object instanceof IIndexable))
  32. return true;
  33. $this->saveToSphinx($object, true);
  34. return true;
  35. }
  36. /**
  37. * Get the [status] column value translated for sphinx supported values.
  38. *
  39. * @return int
  40. */
  41. public function getSphinxId($object)
  42. {
  43. return crc32($object->getId());
  44. }
  45. // TODO remove $force after replace bug solved
  46. /**
  47. * @param IIndexable $object
  48. * @param bool $isInsert
  49. * @param bool $force
  50. * @return string|bool
  51. */
  52. public function getSphinxSaveSql(IIndexable $object, $isInsert = false, $force = false)
  53. {
  54. $id = $object->getIntId();
  55. if(!$id)
  56. {
  57. KalturaLog::err("Object [" . get_class($object) . "] id [" . $object->getId() . "] could not be saved to sphinx, int_id is empty");
  58. return false;
  59. }
  60. // if(!$force && !$isInsert && !$this->saveToSphinxRequired($object))
  61. // return false;
  62. $data = array('id' => $id);
  63. // NOTE: the order matters
  64. $dataStrings = array();
  65. $dataInts = array();
  66. $dataTimes = array();
  67. $fields = $object->getIndexFieldsMap();
  68. foreach($fields as $field => $getterName)
  69. {
  70. $fieldType = $object->getIndexFieldType($field);
  71. $getter = "get{$getterName}";
  72. switch($fieldType)
  73. {
  74. case IIndexable::FIELD_TYPE_STRING:
  75. $dataStrings[$field] = $object->$getter();
  76. break;
  77. case IIndexable::FIELD_TYPE_INTEGER:
  78. $dataInts[$field] = $object->$getter();
  79. break;
  80. case IIndexable::FIELD_TYPE_DATETIME:
  81. $dataTimes[$field] = $object->$getter(null);
  82. break;
  83. }
  84. }
  85. // TODO - remove after solving the replace bug that removes all fields
  86. $pluginInstances = KalturaPluginManager::getPluginInstances('IKalturaSearchDataContributor');
  87. $sphinxPluginsData = array();
  88. foreach($pluginInstances as $pluginName => $pluginInstance)
  89. {
  90. KalturaLog::debug("Loading $pluginName sphinx texts");
  91. $sphinxPluginData = null;
  92. try
  93. {
  94. $sphinxPluginData = $pluginInstance->getSearchData($object);
  95. }
  96. catch(Exception $e)
  97. {
  98. KalturaLog::err($e->getMessage());
  99. continue;
  100. }
  101. if($sphinxPluginData)
  102. {
  103. KalturaLog::debug("Sphinx data for $pluginName [$sphinxPluginData]");
  104. $sphinxPluginsData[] = $sphinxPluginData;
  105. }
  106. }
  107. if(count($sphinxPluginsData))
  108. $dataStrings['plugins_data'] = implode(',', $sphinxPluginsData);
  109. foreach($dataStrings as $key => $value)
  110. {
  111. $search=array("\\","\0","\n","\r","\x1a","'",'"');
  112. $replace=array("\\\\","\\0","\\n","\\r","\\Z","\\'",'\"');
  113. $value = str_replace($search, $replace, $value);
  114. $data[$key] = "'$value'";
  115. }
  116. foreach($dataInts as $key => $value)
  117. {
  118. $value = (int)$value;
  119. $data[$key] = $value;
  120. }
  121. foreach($dataTimes as $key => $value)
  122. {
  123. $value = (int)$value;
  124. $data[$key] = $value;
  125. }
  126. $values = implode(',', $data);
  127. $fields = implode(',', array_keys($data));
  128. $index = kSphinxSearchManager::getSphinxIndexName($object->getObjectIndexName());
  129. $command = 'insert';
  130. if(!$isInsert)
  131. $command = 'replace';
  132. return "$command into $index ($fields) values($values)";
  133. }
  134. /**
  135. * @param string $sql
  136. * @param IIndexable $object
  137. * @return bool
  138. */
  139. public function execSphinx($sql, IIndexable $object)
  140. {
  141. KalturaLog::debug($sql);
  142. $sphinxLog = new SphinxLog();
  143. $sphinxLog->setEntryId($object->getEntryId());
  144. $sphinxLog->setPartnerId($object->getPartnerId());
  145. $sphinxLog->setSql($sql);
  146. $sphinxLog->save(myDbHelper::getConnection(myDbHelper::DB_HELPER_CONN_SPHINX_LOG));
  147. if(!kConf::hasParam('exec_sphinx') || !kConf::get('exec_sphinx'))
  148. return true;
  149. $con = DbManager::getSphinxConnection();
  150. $ret = $con->exec($sql);
  151. if($ret)
  152. return true;
  153. $arr = $con->errorInfo();
  154. KalturaLog::err($arr[2]);
  155. return false;
  156. }
  157. /**
  158. * @param IIndexable $object
  159. * @param bool $isInsert
  160. * @param bool $force
  161. * TODO remove $force after replace bug solved
  162. *
  163. * @return bool
  164. */
  165. public function saveToSphinx(IIndexable $object, $isInsert = false, $force = false)
  166. {
  167. KalturaLog::debug('Updating sphinx for object [' . get_class($object) . '] [' . $object->getId() . ']');
  168. $sql = $this->getSphinxSaveSql($object, $isInsert, $force);
  169. if(!$sql)
  170. return true;
  171. return $this->execSphinx($sql, $object);
  172. }
  173. }