vendor/pimcore/pimcore/lib/Google/Cse.php line 31

Open in your IDE?
  1. <?php
  2. /**
  3. * Pimcore
  4. *
  5. * This source file is available under two different licenses:
  6. * - GNU General Public License version 3 (GPLv3)
  7. * - Pimcore Commercial License (PCL)
  8. * Full copyright and license information is available in
  9. * LICENSE.md which is distributed with this source code.
  10. *
  11. * @copyright Copyright (c) Pimcore GmbH (http://www.pimcore.org)
  12. * @license http://www.pimcore.org/license GPLv3 and PCL
  13. */
  14. namespace Pimcore\Google;
  15. use Exception;
  16. use Google\Service\CustomSearchAPI;
  17. use Google\Service\CustomSearchAPI\Result;
  18. use Google\Service\CustomSearchAPI\Search;
  19. use Pimcore;
  20. use Pimcore\Cache;
  21. use Pimcore\Cache\RuntimeCache;
  22. use Pimcore\Google\Cse\Item;
  23. use Pimcore\Localization\LocaleServiceInterface;
  24. use Pimcore\Model;
  25. use Pimcore\Model\Paginator\PaginateListingInterface;
  26. use ReturnTypeWillChange;
  27. trigger_deprecation('pimcore/pimcore', '10.6', 'The "%s" class is deprecated and will be removed in Pimcore 11.', Cse::class);
  28. /**
  29. * @deprecated since Pimcore 10.6 and will be removed in Pimcore 11
  30. */
  31. class Cse implements PaginateListingInterface
  32. {
  33. /**
  34. * @param string $query
  35. * @param int $offset
  36. * @param int $perPage
  37. * @param array $config
  38. * @param string|null $facet
  39. *
  40. * @return self
  41. */
  42. public static function search($query, $offset = 0, $perPage = 10, array $config = [], $facet = null)
  43. {
  44. $list = new self();
  45. $list->setConfig($config);
  46. $list->setOffset($offset);
  47. $list->setPerPage($perPage);
  48. $list->setQuery($query);
  49. if (!empty($facet)) {
  50. $list->setQuery($list->getQuery() . ' more:' . $facet);
  51. }
  52. return $list;
  53. }
  54. /**
  55. * @return Item[]
  56. *
  57. * @throws Exception
  58. */
  59. public function load()
  60. {
  61. $client = Api::getSimpleClient();
  62. $config = $this->getConfig();
  63. $perPage = $this->getPerPage();
  64. $offset = $this->getOffset();
  65. $query = $this->getQuery();
  66. if ($client) {
  67. $search = new CustomSearchAPI($client);
  68. // determine language
  69. $language = Pimcore::getContainer()->get(LocaleServiceInterface::class)->findLocale();
  70. if ($position = strpos($language, '_')) {
  71. $language = substr($language, 0, $position);
  72. }
  73. if (!array_key_exists('hl', $config) && !empty($language)) {
  74. $config['hl'] = $language;
  75. }
  76. if (!array_key_exists('lr', $config) && !empty($language)) {
  77. $config['lr'] = 'lang_' . $language;
  78. }
  79. if ($query) {
  80. if ($offset) {
  81. $config['start'] = $offset + 1;
  82. }
  83. if (empty($perPage)) {
  84. $perPage = 10;
  85. }
  86. $config['num'] = $perPage;
  87. $config['q'] = $query;
  88. $cacheKey = 'google_cse_' . md5($query . serialize($config));
  89. // this is just a protection so that no query get's sent twice in a request (loops, ...)
  90. if (RuntimeCache::isRegistered($cacheKey)) {
  91. $result = RuntimeCache::get($cacheKey);
  92. } else {
  93. if (!$result = Cache::load($cacheKey)) {
  94. $result = $search->cse->listCse($config);
  95. Cache::save($result, $cacheKey, ['google_cse'], 3600, 999);
  96. RuntimeCache::set($cacheKey, $result);
  97. }
  98. }
  99. $this->readGoogleResponse($result);
  100. return $this->getResults(false);
  101. }
  102. return [];
  103. } else {
  104. throw new Exception('Google Simple API Key is not configured in System-Settings.');
  105. }
  106. }
  107. /**
  108. * @var Item[]
  109. */
  110. public $results = [];
  111. /**
  112. * @var int
  113. */
  114. public $total = 0;
  115. /**
  116. * @var int
  117. */
  118. public $offset = 0;
  119. /**
  120. * @var int
  121. */
  122. public $perPage = 10;
  123. /**
  124. * @var array
  125. */
  126. public $config = [];
  127. /**
  128. * @var string
  129. */
  130. public $query = '';
  131. /**
  132. * @var array
  133. */
  134. public $raw = [];
  135. /**
  136. * @var array
  137. */
  138. public $facets = [];
  139. /**
  140. * @param Search|null $googleResponse
  141. */
  142. public function __construct($googleResponse = null)
  143. {
  144. if ($googleResponse) {
  145. $this->readGoogleResponse($googleResponse);
  146. }
  147. }
  148. /**
  149. * @param Search $googleResponse
  150. */
  151. public function readGoogleResponse(Search $googleResponse)
  152. {
  153. $items = [];
  154. $this->setRaw($googleResponse->getItems());
  155. // set search results
  156. $total = (int)$googleResponse->getSearchInformation()->getTotalResults();
  157. if ($total > 100) {
  158. $total = 100;
  159. }
  160. $this->setTotal($total);
  161. /** @var Result[] $results */
  162. $results = $googleResponse->getItems();
  163. if (is_array($results)) {
  164. foreach ($results as $item) {
  165. $pimcoreResultItem = new Item($item);
  166. // check for relation to document or asset
  167. // first check for an image
  168. $pagemap = $item->getPagemap();
  169. if (is_array($pagemap)) {
  170. if (array_key_exists('cse_image', $item['pagemap']) && is_array($item['pagemap']['cse_image'])) {
  171. if ($item['pagemap']['cse_image'][0]) {
  172. // try to get the asset id
  173. $id = false;
  174. $regexes = [
  175. '/image-thumb__([0-9]+)__/',
  176. '/([0-9]+)\/thumb__/',
  177. '/thumb_([0-9]+)__/',
  178. ];
  179. foreach ($regexes as $regex) {
  180. if (preg_match($regex, $item['pagemap']['cse_image'][0]['src'], $matches)) {
  181. if ($id = (int) $matches[1]) {
  182. break;
  183. }
  184. }
  185. }
  186. if ($id) {
  187. if ($image = Model\Asset::getById($id)) {
  188. if ($image instanceof Model\Asset\Image) {
  189. $pimcoreResultItem->setImage($image);
  190. }
  191. }
  192. }
  193. $pimcoreResultItem->setImage($item['pagemap']['cse_image'][0]['src']);
  194. }
  195. }
  196. }
  197. // now a document
  198. $urlParts = parse_url($item->getLink());
  199. if ($document = Model\Document::getByPath($urlParts['path'])) {
  200. $pimcoreResultItem->setDocument($document);
  201. }
  202. $pimcoreResultItem->setType('searchresult');
  203. $items[] = $pimcoreResultItem;
  204. }
  205. }
  206. $this->setResults($items);
  207. }
  208. /**
  209. * @param int $offset
  210. *
  211. * @return $this
  212. */
  213. public function setOffset($offset)
  214. {
  215. $this->offset = $offset;
  216. return $this;
  217. }
  218. /**
  219. * @return int
  220. */
  221. public function getOffset()
  222. {
  223. return $this->offset;
  224. }
  225. /**
  226. * @param array $raw
  227. *
  228. * @return $this
  229. */
  230. public function setRaw($raw)
  231. {
  232. $this->raw = $raw;
  233. return $this;
  234. }
  235. /**
  236. * @return array
  237. */
  238. public function getRaw()
  239. {
  240. return $this->raw;
  241. }
  242. /**
  243. * @param int $total
  244. *
  245. * @return $this
  246. */
  247. public function setTotal($total)
  248. {
  249. $this->total = $total;
  250. return $this;
  251. }
  252. /**
  253. * @return int
  254. */
  255. public function getTotal()
  256. {
  257. return $this->total;
  258. }
  259. /**
  260. * @param int $perPage
  261. *
  262. * @return $this
  263. */
  264. public function setPerPage($perPage)
  265. {
  266. $this->perPage = $perPage;
  267. return $this;
  268. }
  269. /**
  270. * @return int
  271. */
  272. public function getPerPage()
  273. {
  274. return $this->perPage;
  275. }
  276. /**
  277. * @param array $config
  278. *
  279. * @return $this
  280. */
  281. public function setConfig($config)
  282. {
  283. $this->config = $config;
  284. return $this;
  285. }
  286. /**
  287. * @return array
  288. */
  289. public function getConfig()
  290. {
  291. return $this->config;
  292. }
  293. /**
  294. * @param string $query
  295. *
  296. * @return $this
  297. */
  298. public function setQuery($query)
  299. {
  300. $this->query = $query;
  301. return $this;
  302. }
  303. /**
  304. * @return string
  305. */
  306. public function getQuery()
  307. {
  308. return $this->query;
  309. }
  310. /**
  311. * @param Item[] $results
  312. *
  313. * @return $this
  314. */
  315. public function setResults($results)
  316. {
  317. $this->results = $results;
  318. return $this;
  319. }
  320. /**
  321. * @param bool $retry
  322. *
  323. * @return Item[]
  324. *
  325. * @throws Exception
  326. */
  327. public function getResults($retry = true)
  328. {
  329. if (empty($this->results) && $retry) {
  330. $this->load();
  331. }
  332. return $this->results;
  333. }
  334. /**
  335. * @param array $facets
  336. *
  337. * @return $this
  338. */
  339. public function setFacets($facets)
  340. {
  341. $this->facets = $facets;
  342. return $this;
  343. }
  344. /**
  345. * @return array
  346. */
  347. public function getFacets()
  348. {
  349. return $this->facets;
  350. }
  351. /**
  352. * Methods for PaginateListingInterface
  353. */
  354. /**
  355. * @return int
  356. */
  357. #[ReturnTypeWillChange]
  358. public function count()// : int
  359. {
  360. $this->getResults();
  361. return $this->getTotal();
  362. }
  363. /**
  364. * @param int $offset
  365. * @param int $itemCountPerPage
  366. *
  367. * @return Item[]
  368. *
  369. * @throws Exception
  370. */
  371. public function getItems($offset, $itemCountPerPage)
  372. {
  373. $this->setOffset($offset);
  374. $this->setPerPage($itemCountPerPage);
  375. return $this->load();
  376. }
  377. /**
  378. * Methods for Iterator
  379. */
  380. /**
  381. * @return void
  382. */
  383. #[ReturnTypeWillChange]
  384. public function rewind()// : void
  385. {
  386. reset($this->results);
  387. }
  388. /**
  389. * @return Item|false
  390. */
  391. #[ReturnTypeWillChange]
  392. public function current()// : Item|false
  393. {
  394. $this->getResults();
  395. return current($this->results);
  396. }
  397. /**
  398. * @return int|null
  399. */
  400. #[ReturnTypeWillChange]
  401. public function key()// : int|null
  402. {
  403. $this->getResults();
  404. return key($this->results);
  405. }
  406. /**
  407. * @return void
  408. */
  409. #[ReturnTypeWillChange]
  410. public function next()// : void
  411. {
  412. $this->getResults();
  413. next($this->results);
  414. }
  415. /**
  416. * @return bool
  417. */
  418. #[ReturnTypeWillChange]
  419. public function valid()// : bool
  420. {
  421. $this->getResults();
  422. return $this->current() !== false;
  423. }
  424. }