/inc/class-search-functions.php

https://github.com/NateJacobs/Brickset-API · PHP · 697 lines · 314 code · 104 blank · 279 comment · 53 complexity · b1fd942e8a07704874b13f6fde43eda4 MD5 · raw file

  1. <?php
  2. class BricksetAPISearch extends BricksetAPIUtilities
  3. {
  4. /**
  5. * Start things off when class is instantiated
  6. *
  7. * @author Nate Jacobs
  8. * @date 2/22/13
  9. * @since 1.0
  10. */
  11. public function __construct()
  12. {
  13. }
  14. /**
  15. * Get a list of all themes
  16. *
  17. * Brickset returns the themeData response.
  18. * See webservice-definition.json for all the fields returned.
  19. *
  20. * @author Nate Jacobs
  21. * @since 0.1
  22. * @updated 1.4
  23. *
  24. * @return object a listing of all the themes
  25. */
  26. public function get_themes()
  27. {
  28. $transient = 'bs_theme_list';
  29. // Have we stored a transient?
  30. if( false === get_transient( $transient ) )
  31. {
  32. $response = $this->remote_request( 'get', 'listThemes' );
  33. if( is_wp_error( $response ) )
  34. {
  35. return $response;
  36. }
  37. set_transient( $transient, $response, apply_filters( 'bs_get_themes_transient', DAY_IN_SECONDS ) );
  38. }
  39. // Return a SimpleXML object
  40. return new SimpleXMLElement( get_transient( $transient ) );
  41. }
  42. /**
  43. * Get a list of all subthemes for a given theme
  44. *
  45. * Brickset returns the subthemeData response.
  46. * See webservice-definition.json for all the fields returned.
  47. *
  48. * @author Nate Jacobs
  49. * @since 0.1
  50. * @updated 1.0
  51. *
  52. * @param string
  53. *
  54. * @return object
  55. */
  56. public function get_subthemes( $theme )
  57. {
  58. // Is it a valid string
  59. if( is_wp_error( $validate_theme = $this->validate_theme_subtheme( $theme ) ) )
  60. return $validate_theme;
  61. $theme = sanitize_text_field( strtolower( $theme ) );
  62. $transient_theme = str_replace( " ", "", $theme );
  63. $transient = 'bs_'.$transient_theme.'_subthemes';
  64. // Have we stored a transient?
  65. if( false === get_transient( $transient ) )
  66. {
  67. $args = array( 'theme' => $theme );
  68. $params = $this->build_bs_query( $args );
  69. $response = $this->remote_request( 'get', 'listSubthemes', $params );
  70. if( is_wp_error( $response ) )
  71. {
  72. return $response;
  73. }
  74. set_transient( $transient, $response, apply_filters( 'bs_get_subthemes_transient', DAY_IN_SECONDS ) );
  75. }
  76. // Get it and return a SimpleXML object
  77. return new SimpleXMLElement( get_transient( $transient ) );
  78. }
  79. /**
  80. * Get a list of years a theme was available
  81. *
  82. * Brickset returns the yearData response.
  83. * See webservice-definition.json for all the fields returned.
  84. *
  85. * @author Nate Jacobs
  86. * @since 0.1
  87. * @updated 1.0
  88. *
  89. * @param string
  90. *
  91. * @return object
  92. */
  93. public function get_theme_years( $theme )
  94. {
  95. // Is it a valid string
  96. if( is_wp_error( $validate_theme = $this->validate_theme_subtheme( $theme ) ) )
  97. return $validate_theme;
  98. $theme = sanitize_text_field( strtolower( $theme ) );
  99. $transient_theme = str_replace( " ", "", $theme );
  100. $transient = 'bs_'.$transient_theme.'_years';
  101. // Have we stored a transient?
  102. if( false === get_transient( $transient ) )
  103. {
  104. $args = array( 'theme' => $theme );
  105. $params = $this->build_bs_query( $args );
  106. $response = $this->remote_request( 'get', 'listYears', $params );
  107. if( is_wp_error( $response ) )
  108. {
  109. return $response;
  110. }
  111. set_transient( $transient, $response, apply_filters( 'bs_get_theme_years_transient', DAY_IN_SECONDS ) );
  112. }
  113. // Get it and return a SimpleXML object
  114. return new SimpleXMLElement( get_transient( $transient ) );
  115. }
  116. /**
  117. * Get a list of the most searched for terms
  118. *
  119. * Brickset returns the searchData response
  120. * See webservice-definition.json for all the fields returned.
  121. *
  122. * @author Nate Jacobs
  123. * @since 0.1
  124. * @updated 1.0
  125. *
  126. * @return object
  127. */
  128. public function get_popular_searches()
  129. {
  130. $transient = 'bs_popular_searches';
  131. // Have we stored a transient?
  132. if( false === get_transient( $transient ) )
  133. {
  134. $response = $this->remote_request( 'get', 'popularSearches' );
  135. if( is_wp_error( $response ) )
  136. {
  137. return $response;
  138. }
  139. set_transient( $transient, $response, apply_filters( 'bs_get_popular_searches_transient', HOUR_IN_SECONDS ) );
  140. }
  141. // Get it and return a SimpleXML object
  142. return new SimpleXMLElement( get_transient( $transient ) );
  143. }
  144. /**
  145. * Get all sets updated since a given date
  146. *
  147. * Brickset returns the setData response.
  148. * See webservice-definition.json for all the fields returned.
  149. *
  150. * @author Nate Jacobs
  151. * @since 0.1
  152. * @updated 1.0
  153. *
  154. * @param string use format of 'mm/dd/yyyy'
  155. *
  156. * @return object
  157. */
  158. public function get_updated_since( $date )
  159. {
  160. $exploded_date = explode( '/', $date );
  161. // Is this a date in the correct format?
  162. if( false === checkdate( $exploded_date[0], $exploded_date[1], $exploded_date[2] ) )
  163. return new WP_Error( 'not-a-date-format', __( 'The date is not formatted correctly.', 'bs_api' ) );
  164. // Is it a valid year
  165. if( is_wp_error( $validate_year = $this->validate_year( $exploded_date[2] ) ) )
  166. return $validate_year;
  167. $transient_date = str_replace( '/', '', $date );
  168. $transient = 'bs_updated_since_'.$transient_date;
  169. // Have we stored a transient?
  170. if( false === get_transient( $transient ) )
  171. {
  172. $params = 'apiKey='.$this->get_api_key().'&sinceDate='.$date;
  173. $response = $this->remote_request( 'get', 'updatedSince', $params );
  174. if( is_wp_error( $response ) )
  175. {
  176. return $response;
  177. }
  178. set_transient( $transient, $response, apply_filters( 'bs_get_updated_since_transient', DAY_IN_SECONDS ) );
  179. }
  180. // Get it and return a SimpleXML object
  181. return new SimpleXMLElement( get_transient( $transient ) );
  182. }
  183. /**
  184. * Get Set Info by Number
  185. *
  186. * Pass a set number and get all the information about that set.
  187. * Returns the setData response.
  188. * See webservice-definition.json for all the fields returned.
  189. *
  190. * @author Nate Jacobs
  191. * @since 0.1
  192. * @updated 1.0
  193. *
  194. * @param string set number
  195. * @param int user_id
  196. * @param bool true = return wanted
  197. * @param bool true = return owned
  198. *
  199. * @return object
  200. */
  201. public function get_by_number( $number = '', $args = '' )
  202. {
  203. $defaults = array(
  204. 'owned' => false,
  205. 'wanted' => false,
  206. 'user_id' => ''
  207. );
  208. // Is there a number?
  209. if( empty( $number ) )
  210. return new WP_Error( 'no-set-number', __( 'No set number requested.', 'bs_api' ) );
  211. // Check on the number for variants
  212. if( is_wp_error( $sets = $this->validate_set_number( $number ) ) )
  213. return $sets;
  214. $args['set_number'] = $sets;
  215. $args = wp_parse_args( $args, $defaults );
  216. return $this->search( $args );
  217. }
  218. /**
  219. * Get Wanted Sets
  220. *
  221. * Get all the wanted sets by the specified user.
  222. * Returns the setData response.
  223. * See webservice-definition.json for all the fields returned.
  224. *
  225. * @author Nate Jacobs
  226. * @since 0.2
  227. * @updated 1.0
  228. *
  229. * @param int user ID
  230. *
  231. * @return object
  232. */
  233. public function get_wanted( $user_id = '' )
  234. {
  235. // Is there a user?
  236. if( empty( $user_id ) )
  237. return new WP_Error( 'no-user-specified', __( 'No user specified.', 'bs_api' ) );
  238. $args['user_id'] = $user_id;
  239. $args['wanted'] = true;
  240. return $this->search( $args );
  241. }
  242. /**
  243. * Get Owned Sets
  244. *
  245. * Get all the sets owned by the specified user.
  246. * Returns the setData resposne.
  247. * See webservice-definition.json for all the fields returned.
  248. *
  249. * @author Nate Jacobs
  250. * @since 0.3
  251. * @updated 1.0
  252. *
  253. * @param int user_id
  254. *
  255. * @return object
  256. */
  257. public function get_owned( $user_id = '' )
  258. {
  259. // Is there a user?
  260. if( empty( $user_id ) )
  261. return new WP_Error( 'no-user-specified', __( 'No user specified.', 'bs_api' ) );
  262. $args['user_id'] = $user_id;
  263. $args['owned'] = true;
  264. return $this->search( $args );
  265. }
  266. /**
  267. * Get Set Info by Theme
  268. *
  269. * Pass a theme and get all the information about the sets in that theme.
  270. * Returns the setData response.
  271. * See webservice-definition.json for all the fields returned.
  272. *
  273. * @author Nate Jacobs
  274. * @since 0.1
  275. * @updated 1.0
  276. *
  277. * @param string
  278. * @param array user_id, owned, wanted
  279. * @param int
  280. * @param bool
  281. * @param bool
  282. *
  283. * @return object
  284. */
  285. public function get_by_theme( $theme = '', $args = '' )
  286. {
  287. $defaults = array(
  288. 'owned' => false,
  289. 'wanted' => false,
  290. 'user_id' => ''
  291. );
  292. // Is there a theme?
  293. if( empty( $theme ) )
  294. return new WP_Error( 'no-theme', __( 'No theme requested.', 'bs_api' ) );
  295. $args['theme'] = $theme;
  296. $args = wp_parse_args( $args, $defaults );
  297. return $this->search( $args );
  298. }
  299. /**
  300. * Get Set Info by Subtheme
  301. *
  302. * Pass a subtheme and get all the information about the sets in that subtheme.
  303. * Returns the setData response.
  304. * See webservice-definition.json for all the fields returned.
  305. *
  306. * @author Nate Jacobs
  307. * @since 0.1
  308. * @updated 1.0
  309. *
  310. * @param int
  311. * @param array (user_id, owned, wanted)
  312. * @param int
  313. * @param int
  314. * @param int
  315. *
  316. * @return object
  317. */
  318. public function get_by_subtheme( $subtheme = '', $args = '' )
  319. {
  320. $defaults = array(
  321. 'owned' => false,
  322. 'wanted' => false,
  323. 'user_id' => ''
  324. );
  325. // Is there a subtheme?
  326. if( empty( $subtheme ) )
  327. return new WP_Error( 'no-subtheme', __( 'No subtheme requested.', 'bs_api' ) );
  328. $args['subtheme'] = $subtheme;
  329. $args = wp_parse_args( $args, $defaults );
  330. return $this->search( $args );
  331. }
  332. /**
  333. * Get Set Info by Year
  334. *
  335. * Pass a year and get all the information about the sets produced that year.
  336. * Returns the setData response
  337. * See webservice-definition.json for all the fields returned.
  338. *
  339. * @author Nate Jacobs
  340. * @since 0.1
  341. * @updated 1.0
  342. *
  343. * @param int
  344. * @param array user_id, owned, wanted
  345. * @param int
  346. * @param int
  347. * @param int
  348. *
  349. * @return object
  350. */
  351. public function get_by_year( $year = '', $args = '' )
  352. {
  353. $defaults = array(
  354. 'owned' => false,
  355. 'wanted' => false,
  356. 'user_id' => ''
  357. );
  358. // Is there a year?
  359. if( empty( $year ) )
  360. return new WP_Error( 'no-year', __( 'No year requested.', 'bs_api' ) );
  361. $args['year'] = $year;
  362. $args = wp_parse_args( $args, $defaults );
  363. return $this->search( $args );
  364. }
  365. /**
  366. * Get Instructions
  367. *
  368. * Retrieve instructions link by Brickset set ID.
  369. * Returns the instructionsData response
  370. * See webservice-definition.json for all the fields returned.
  371. *
  372. * @author Nate Jacobs
  373. * @date 3/22/13
  374. * @since 1.1
  375. *
  376. * @param string
  377. *
  378. * @return object
  379. */
  380. public function get_instructions( $set_id = '' )
  381. {
  382. // Is there a setID?
  383. if( empty( $set_id ) )
  384. return new WP_Error( 'no-set-id', __( 'No set ID requested.', 'bs_api' ) );
  385. // Is the string numeric
  386. if( is_wp_error( $validate_set_id = $this->validate_set_id( $set_id ) ) )
  387. return $validate_set_id;
  388. $transient = 'bs_instructions'.$set_id;
  389. // Have we stored a transient?
  390. if( false === get_transient( $transient ) )
  391. {
  392. $params = 'setID='.$set_id;
  393. $response = $this->remote_request( 'get', 'listInstructions', $params );
  394. if( is_wp_error( $response ) )
  395. {
  396. return $response;
  397. }
  398. set_transient( $transient, $response, apply_filters( 'bs_get_instructions_transient', DAY_IN_SECONDS ) );
  399. }
  400. // Get it and return a SimpleXML object
  401. return new SimpleXMLElement( get_transient( $transient ) );
  402. }
  403. /**
  404. * Get by Set ID
  405. *
  406. * Retrieves a single set by Brickset internal set ID
  407. * Returns the setData response
  408. * See webservice-definition.json for all the fields returned.
  409. *
  410. * @author Nate Jacobs
  411. * @date 3/24/13
  412. * @since 1.1
  413. *
  414. * @param string
  415. *
  416. * @return object
  417. */
  418. public function get_by_set_id( $set_id )
  419. {
  420. // Is there a setID?
  421. if( empty( $set_id ) )
  422. return new WP_Error( 'no-set-id', __( 'No set ID requested.', 'bs_api' ) );
  423. // Is the string numeric
  424. if( is_wp_error( $validate_set_id = $this->validate_set_id( $set_id ) ) )
  425. return $validate_set_id;
  426. $transient = 'bs_set_id_search_'.$set_id;
  427. // Have we stored a transient?
  428. if( false === get_transient( $transient ) )
  429. {
  430. $params = 'setID='.$set_id;
  431. $response = $this->remote_request( 'get', 'searchBySetID', $params );
  432. if( is_wp_error( $response ) )
  433. {
  434. return $response;
  435. }
  436. set_transient( $transient, $response, apply_filters( 'bs_get_by_set_id_transient', DAY_IN_SECONDS ) );
  437. }
  438. // Get it and return a SimpleXML object
  439. return new SimpleXMLElement( get_transient( $transient ) );
  440. }
  441. /**
  442. * Search the Brickset DB with a given set of criteria
  443. *
  444. * Provides method for searching Brickset's set database
  445. * Returns the setData response
  446. * See webservice-definition.json for all the fields returned.
  447. *
  448. * @author Nate Jacobs
  449. * @since 0.1
  450. *
  451. * @param array theme, subtheme, set number, year, owned, wanted, query, user id
  452. *
  453. * @return object
  454. */
  455. public function search( $args = '' )
  456. {
  457. $defaults = array(
  458. 'theme' => '',
  459. 'subtheme' => '',
  460. 'set_number'=> '',
  461. 'year' => '',
  462. 'owned' => false,
  463. 'wanted' => false,
  464. 'query' => '',
  465. 'user_id' => ''
  466. );
  467. // Is there any criteria to search?
  468. if( empty( $args ) )
  469. return new WP_Error( 'no-search-criteria', __( 'No search criteria specified.', 'bs_api' ) );
  470. $args = wp_parse_args( $args, $defaults );
  471. // Is it a valid year
  472. if( !empty( $args['year'] ) )
  473. {
  474. if( is_wp_error( $validate_year = $this->validate_year( $args['year'] ) ) )
  475. return $validate_year;
  476. }
  477. // Is it a valid user_id?
  478. if( !empty( $args['user_id'] ) )
  479. {
  480. if( is_wp_error( $validate_user = $this->validate_user( $args['user_id'] ) ) )
  481. return $validate_user;
  482. }
  483. // Is it a valid string
  484. if( !empty( $args['theme'] ) || !empty( $args['subtheme'] ) )
  485. {
  486. if( is_wp_error( $validate_string = $this->validate_theme_subtheme( $args['theme'], $args['subtheme'] ) ) )
  487. return $validate_string;
  488. }
  489. // Is it a valid string?
  490. if( !empty( $args['query'] ) )
  491. {
  492. if( !is_string( $args['query'] ) )
  493. return new WP_Error( 'not-valid-query', __( 'The query requested is not a valid string.', 'bs_api' ) );
  494. }
  495. // Was a true or false passed for owned and wanted?
  496. if( is_wp_error( $validate_owned_wanted = $this->validate_owned_wanted( $args['owned'], $args['wanted'] ) ) )
  497. return $validate_owned_wanted;
  498. if( is_wp_error( $sets = $this->validate_set_number( $args['set_number'] ) ) )
  499. return $sets;
  500. $args['set_number'] = $sets;
  501. $args['theme'] = strtolower( $args['theme'] );
  502. $args['subtheme'] = strtolower( $args['subtheme'] );
  503. $args['query'] = strtolower( $args['query'] );
  504. $transient_sets = str_replace( array( ',', '-' ), '', $args['set_number'] );
  505. $transient_year = str_replace( ",", '', $args['year'] );
  506. $transient_theme = str_replace( array( ',', '-', " " ), '', $args['theme'] );
  507. $transient_subtheme = str_replace( array( ',', '-', " " ), '', $args['subtheme'] );
  508. $transient_query = str_replace( array( ',', '-', " " ), '', $args['query'] );
  509. $transient = 'bs_search_'.$transient_theme.$transient_subtheme.$transient_sets.$transient_year.$transient_query.'_user-'.$args['user_id'].'_want-'.$args['wanted'].'_own-'.$args['owned'];
  510. if( false === get_transient( $transient ) )
  511. {
  512. $params = $this->build_bs_query( $args );
  513. $response = $this->remote_request( 'get', 'search', $params );
  514. if( is_wp_error( $response ) )
  515. {
  516. return $response;
  517. }
  518. set_transient( $transient, $response, apply_filters( 'bs_search_transient', DAY_IN_SECONDS ) );
  519. }
  520. return new SimpleXMLElement( get_transient( $transient ) );
  521. }
  522. /**
  523. * Get Minifig Collection
  524. *
  525. * Retrieve a list of all minifigs owned or wanted by a user that optionally match a query.
  526. * Leave owned and wanted blank to retrieve those owned and wanted, or set one of them to '1' to get just owned or just wanted.
  527. * Query can be a complete minifig number (e.g. 'hp001'), or just a prefix (e.g. 'hp'). Leave blank to retrieve all.
  528. * Returns the minifigCollectionData response
  529. * See webservice-definition.json for all the fields returned.
  530. *
  531. * @author Nate Jacobs
  532. * @date 3/28/13
  533. * @since 1.1
  534. *
  535. * @param int
  536. * @param array query, owned, wanted
  537. *
  538. * @return object
  539. */
  540. public function get_minifig_collection( $user_id, $args = '' )
  541. {
  542. $defaults = array(
  543. 'query' => '',
  544. 'owned' => '',
  545. 'wanted' => ''
  546. );
  547. if( empty( $args ) )
  548. return new WP_Error( 'missing-arguments', __( 'You must include at least one of the following: query, owned, or wanted.', 'bs_api' ) );
  549. $args = wp_parse_args( $args, $defaults );
  550. // Is it a valid user?
  551. if( is_wp_error( $validate_user = $this->validate_user( $user_id ) ) )
  552. return $validate_user;
  553. // Is it a valid string?
  554. if( !empty( $args['query'] ) )
  555. {
  556. if( !is_string( $args['query'] ) )
  557. return new WP_Error( 'not-valid-query', __( 'The query requested is not a valid string.', 'bs_api' ) );
  558. }
  559. // Was a true or false passed for owned?
  560. if( !empty( $args['owned'] ) )
  561. {
  562. if( is_wp_error( $validate_owned = $this->validate_owned_wanted( $args['owned'] ) ) )
  563. return $validate_owned;
  564. }
  565. // Was a true or false passed for wanted?
  566. if( !empty( $args['wanted'] ) )
  567. {
  568. if( is_wp_error( $validate_wanted = $this->validate_owned_wanted( $args['wanted'] ) ) )
  569. return $validate_wanted;
  570. }
  571. $args['query'] = strtolower( $args['query'] );
  572. $transient_query = str_replace( array( ',', '-', " " ), '', $args['query'] );
  573. $transient = 'bs_minifig_'.$transient_query.'_user-'.$user_id.'_want-'.$args['wanted'].'_own-'.$args['owned'];
  574. if( false === get_transient( $transient ) )
  575. {
  576. $params = array(
  577. 'body' => array(
  578. 'userHash' => $this->get_user_hash( $user_id ),
  579. 'query' => sanitize_text_field( $args['query'] ),
  580. 'owned' => $args['owned'],
  581. 'wanted' => $args['wanted']
  582. )
  583. );
  584. $response = $this->remote_request( 'post', 'searchMinifigCollection', $params );
  585. if( is_wp_error( $response ) )
  586. {
  587. return $response;
  588. }
  589. set_transient( $transient, $response, apply_filters( 'bs_get_minifig_collection_transient', DAY_IN_SECONDS ) );
  590. }
  591. return new SimpleXMLElement( get_transient( $transient ) );
  592. }
  593. }