488
+    '''
489
+    cameras = ['rtsp://username:password@ip_address:554/user=username_password='password'_channel=channel_number_stream=0.sdp',
490
+    'rtsp://username:password@ip_address:554/user=username_password='password'_channel=channel_number_stream=0.sdp']
491
+    '''
492
+    cameras = ['rtsp://admin:@Unv123456@192.168.10.252:554/unicast/c1/s1/live']
493
+    return cameras[int(id)]
494
+#  for cctv camera use rtsp://username:password@ip_address:554/user=username_password='password'_channel=channel_number_stream=0.sdp' instead of camera
495
+#  for webcam use zero(0)
496
+
497
+
498
+def gen_frames(camera_id):
499
+
500
+    cam = find_camera(camera_id)
501
+    cap=  cv2.VideoCapture(cam)
502
+
503
+    while True:
504
+        # for cap in caps:
505
+        # # Capture frame-by-frame
506
+        success, frame = cap.read()  # read the camera frame
507
+        if not success:
508
+            break
509
+        else:
510
+            ret, buffer = cv2.imencode('.jpg', frame)
511
+            frame = buffer.tobytes()
512
+            yield (b'--frame\r\n'
513
+                b'Content-Type: image/jpeg\r\n\r\n' + frame + b'\r\n')  # concat frame one by one and show result
514
+@app.route('/video_feed/<string:id>/', methods=["GET"])
515
+def video_feed(id):
516
+
517
+    """Video streaming route. Put this in the src attribute of an img tag."""
518
+    '''
519
+    return Response(gen_frames(id),
520
+                    mimetype='multipart/x-mixed-replace; boundary=frame')
521
+    '''
522
+    return Response(process_video(),
523
+                    mimetype='multipart/x-mixed-replace; boundary=frame')
524
+
525
+@app.route('/', methods=["GET"])
526
+def index():
527
+    return render_template('index.html')
528
+
529
+
530
+if __name__ == '__main__':
531
+    app.run(debug=True, port=9099)

二進制
cap/frame0.jpg


二進制
cap/frame1.jpg


二進制
cap/frame10.jpg


二進制
cap/frame100.jpg


二進制
cap/frame101.jpg


二進制
cap/frame102.jpg


二進制
cap/frame103.jpg


二進制
cap/frame104.jpg


二進制
cap/frame105.jpg


二進制
cap/frame106.jpg


二進制
cap/frame107.jpg


二進制
cap/frame108.jpg


二進制
cap/frame109.jpg


二進制
cap/frame11.jpg


二進制
cap/frame110.jpg


二進制
cap/frame111.jpg


二進制
cap/frame112.jpg


二進制
cap/frame113.jpg


二進制
cap/frame114.jpg


二進制
cap/frame115.jpg


二進制
cap/frame116.jpg


二進制
cap/frame117.jpg


二進制
cap/frame118.jpg


二進制
cap/frame119.jpg


二進制
cap/frame12.jpg


二進制
cap/frame120.jpg


二進制
cap/frame121.jpg


二進制
cap/frame122.jpg


二進制
cap/frame123.jpg


二進制
cap/frame124.jpg


二進制
cap/frame125.jpg


二進制
cap/frame126.jpg


二進制
cap/frame127.jpg


二進制
cap/frame128.jpg


二進制
cap/frame129.jpg


二進制
cap/frame13.jpg


二進制
cap/frame130.jpg


二進制
cap/frame131.jpg


二進制
cap/frame132.jpg


二進制
cap/frame133.jpg


二進制
cap/frame134.jpg


二進制
cap/frame135.jpg


二進制
cap/frame136.jpg


二進制
cap/frame137.jpg


二進制
cap/frame138.jpg


二進制
cap/frame139.jpg


二進制
cap/frame14.jpg


二進制
cap/frame140.jpg


二進制
cap/frame141.jpg


二進制
cap/frame142.jpg


二進制
cap/frame143.jpg


二進制
cap/frame144.jpg


二進制
cap/frame145.jpg


二進制
cap/frame146.jpg


二進制
cap/frame147.jpg


二進制
cap/frame148.jpg


二進制
cap/frame149.jpg


二進制
cap/frame15.jpg


二進制
cap/frame150.jpg


二進制
cap/frame151.jpg


二進制
cap/frame152.jpg


二進制
cap/frame153.jpg


二進制
cap/frame154.jpg


二進制
cap/frame155.jpg


二進制
cap/frame156.jpg


二進制
cap/frame157.jpg


二進制
cap/frame158.jpg


二進制
cap/frame159.jpg


二進制
cap/frame16.jpg


二進制
cap/frame160.jpg


二進制
cap/frame161.jpg


二進制
cap/frame162.jpg


二進制
cap/frame163.jpg


二進制
cap/frame164.jpg


二進制
cap/frame165.jpg


二進制
cap/frame166.jpg


二進制
cap/frame167.jpg


二進制
cap/frame168.jpg


二進制
cap/frame169.jpg


二進制
cap/frame17.jpg


二進制
cap/frame170.jpg


二進制
cap/frame171.jpg


二進制
cap/frame172.jpg


二進制
cap/frame173.jpg


二進制
cap/frame174.jpg


二進制
cap/frame175.jpg


二進制
cap/frame176.jpg


二進制
cap/frame177.jpg


二進制
cap/frame178.jpg


二進制
cap/frame179.jpg


二進制
cap/frame18.jpg


二進制
cap/frame180.jpg


二進制
cap/frame181.jpg


+ 0 - 0
cap/frame182.jpg


部分文件因文件數量過多而無法顯示

golf/tge - Gogs: Simplico Git Service

Geen omschrijving

golf d8e79ace03 index commit 3 jaren geleden
..
AD.js d8e79ace03 index commit 3 jaren geleden
AE.js d8e79ace03 index commit 3 jaren geleden
AF.js d8e79ace03 index commit 3 jaren geleden
AG.js d8e79ace03 index commit 3 jaren geleden
AI.js d8e79ace03 index commit 3 jaren geleden
AL.js d8e79ace03 index commit 3 jaren geleden
AM.js d8e79ace03 index commit 3 jaren geleden
AO.js d8e79ace03 index commit 3 jaren geleden
AR.js d8e79ace03 index commit 3 jaren geleden
AS.js d8e79ace03 index commit 3 jaren geleden
AT.js d8e79ace03 index commit 3 jaren geleden
AU.js d8e79ace03 index commit 3 jaren geleden
AW.js d8e79ace03 index commit 3 jaren geleden
AX.js d8e79ace03 index commit 3 jaren geleden
AZ.js d8e79ace03 index commit 3 jaren geleden
BA.js d8e79ace03 index commit 3 jaren geleden
BB.js d8e79ace03 index commit 3 jaren geleden
BD.js d8e79ace03 index commit 3 jaren geleden
BE.js d8e79ace03 index commit 3 jaren geleden
BF.js d8e79ace03 index commit 3 jaren geleden
BG.js d8e79ace03 index commit 3 jaren geleden
BH.js d8e79ace03 index commit 3 jaren geleden
BI.js d8e79ace03 index commit 3 jaren geleden
BJ.js d8e79ace03 index commit 3 jaren geleden
BM.js d8e79ace03 index commit 3 jaren geleden
BN.js d8e79ace03 index commit 3 jaren geleden
BO.js d8e79ace03 index commit 3 jaren geleden
BR.js d8e79ace03 index commit 3 jaren geleden
BS.js d8e79ace03 index commit 3 jaren geleden
BT.js d8e79ace03 index commit 3 jaren geleden
BW.js d8e79ace03 index commit 3 jaren geleden
BY.js d8e79ace03 index commit 3 jaren geleden
BZ.js d8e79ace03 index commit 3 jaren geleden
CA.js d8e79ace03 index commit 3 jaren geleden
CD.js d8e79ace03 index commit 3 jaren geleden
CF.js d8e79ace03 index commit 3 jaren geleden
CG.js d8e79ace03 index commit 3 jaren geleden
CH.js d8e79ace03 index commit 3 jaren geleden
CI.js d8e79ace03 index commit 3 jaren geleden
CK.js d8e79ace03 index commit 3 jaren geleden
CL.js d8e79ace03 index commit 3 jaren geleden
CM.js d8e79ace03 index commit 3 jaren geleden
CN.js d8e79ace03 index commit 3 jaren geleden
CO.js d8e79ace03 index commit 3 jaren geleden
CR.js d8e79ace03 index commit 3 jaren geleden
CU.js d8e79ace03 index commit 3 jaren geleden
CV.js d8e79ace03 index commit 3 jaren geleden
CX.js d8e79ace03 index commit 3 jaren geleden
CY.js d8e79ace03 index commit 3 jaren geleden
CZ.js d8e79ace03 index commit 3 jaren geleden
DE.js d8e79ace03 index commit 3 jaren geleden
DJ.js d8e79ace03 index commit 3 jaren geleden
DK.js d8e79ace03 index commit 3 jaren geleden
DM.js d8e79ace03 index commit 3 jaren geleden
DO.js d8e79ace03 index commit 3 jaren geleden
DZ.js d8e79ace03 index commit 3 jaren geleden
EC.js d8e79ace03 index commit 3 jaren geleden
EE.js d8e79ace03 index commit 3 jaren geleden
EG.js d8e79ace03 index commit 3 jaren geleden
ER.js d8e79ace03 index commit 3 jaren geleden
ES.js d8e79ace03 index commit 3 jaren geleden
ET.js d8e79ace03 index commit 3 jaren geleden
FI.js d8e79ace03 index commit 3 jaren geleden
FJ.js d8e79ace03 index commit 3 jaren geleden
FK.js d8e79ace03 index commit 3 jaren geleden
FM.js d8e79ace03 index commit 3 jaren geleden
FO.js d8e79ace03 index commit 3 jaren geleden
FR.js d8e79ace03 index commit 3 jaren geleden
GA.js d8e79ace03 index commit 3 jaren geleden
GB.js d8e79ace03 index commit 3 jaren geleden
GD.js d8e79ace03 index commit 3 jaren geleden
GE.js d8e79ace03 index commit 3 jaren geleden
GF.js d8e79ace03 index commit 3 jaren geleden
GG.js d8e79ace03 index commit 3 jaren geleden
GH.js d8e79ace03 index commit 3 jaren geleden
GI.js d8e79ace03 index commit 3 jaren geleden
GL.js d8e79ace03 index commit 3 jaren geleden
GM.js d8e79ace03 index commit 3 jaren geleden
GN.js d8e79ace03 index commit 3 jaren geleden
GP.js d8e79ace03 index commit 3 jaren geleden
GQ.js d8e79ace03 index commit 3 jaren geleden
GR.js d8e79ace03 index commit 3 jaren geleden
GT.js d8e79ace03 index commit 3 jaren geleden
GU.js d8e79ace03 index commit 3 jaren geleden
GW.js d8e79ace03 index commit 3 jaren geleden
GY.js d8e79ace03 index commit 3 jaren geleden
HK.js d8e79ace03 index commit 3 jaren geleden
HN.js d8e79ace03 index commit 3 jaren geleden
HR.js d8e79ace03 index commit 3 jaren geleden
HT.js d8e79ace03 index commit 3 jaren geleden
HU.js d8e79ace03 index commit 3 jaren geleden
ID.js d8e79ace03 index commit 3 jaren geleden
IE.js d8e79ace03 index commit 3 jaren geleden
IL.js d8e79ace03 index commit 3 jaren geleden
IM.js d8e79ace03 index commit 3 jaren geleden
IN.js d8e79ace03 index commit 3 jaren geleden
IQ.js d8e79ace03 index commit 3 jaren geleden
IR.js d8e79ace03 index commit 3 jaren geleden
IS.js d8e79ace03 index commit 3 jaren geleden
IT.js d8e79ace03 index commit 3 jaren geleden
JE.js d8e79ace03 index commit 3 jaren geleden
JM.js d8e79ace03 index commit 3 jaren geleden
JO.js d8e79ace03 index commit 3 jaren geleden
JP.js d8e79ace03 index commit 3 jaren geleden
KE.js d8e79ace03 index commit 3 jaren geleden
KG.js d8e79ace03 index commit 3 jaren geleden
KH.js d8e79ace03 index commit 3 jaren geleden
KI.js d8e79ace03 index commit 3 jaren geleden
KM.js d8e79ace03 index commit 3 jaren geleden
KN.js d8e79ace03 index commit 3 jaren geleden
KP.js d8e79ace03 index commit 3 jaren geleden
KR.js d8e79ace03 index commit 3 jaren geleden
KW.js d8e79ace03 index commit 3 jaren geleden
KY.js d8e79ace03 index commit 3 jaren geleden
KZ.js d8e79ace03 index commit 3 jaren geleden
LA.js d8e79ace03 index commit 3 jaren geleden
LB.js d8e79ace03 index commit 3 jaren geleden
LC.js d8e79ace03 index commit 3 jaren geleden
LI.js d8e79ace03 index commit 3 jaren geleden
LK.js d8e79ace03 index commit 3 jaren geleden
LR.js d8e79ace03 index commit 3 jaren geleden
LS.js d8e79ace03 index commit 3 jaren geleden
LT.js d8e79ace03 index commit 3 jaren geleden
LU.js d8e79ace03 index commit 3 jaren geleden
LV.js d8e79ace03 index commit 3 jaren geleden
LY.js d8e79ace03 index commit 3 jaren geleden
MA.js d8e79ace03 index commit 3 jaren geleden
MC.js d8e79ace03 index commit 3 jaren geleden
MD.js d8e79ace03 index commit 3 jaren geleden
ME.js d8e79ace03 index commit 3 jaren geleden
MG.js d8e79ace03 index commit 3 jaren geleden
MH.js d8e79ace03 index commit 3 jaren geleden
MK.js d8e79ace03 index commit 3 jaren geleden
ML.js d8e79ace03 index commit 3 jaren geleden
MM.js d8e79ace03 index commit 3 jaren geleden
MN.js d8e79ace03 index commit 3 jaren geleden
MO.js d8e79ace03 index commit 3 jaren geleden
MP.js d8e79ace03 index commit 3 jaren geleden
MQ.js d8e79ace03 index commit 3 jaren geleden
MR.js d8e79ace03 index commit 3 jaren geleden
MS.js d8e79ace03 index commit 3 jaren geleden
MT.js d8e79ace03 index commit 3 jaren geleden
MU.js d8e79ace03 index commit 3 jaren geleden
MV.js d8e79ace03 index commit 3 jaren geleden
MW.js d8e79ace03 index commit 3 jaren geleden
MX.js d8e79ace03 index commit 3 jaren geleden
MY.js d8e79ace03 index commit 3 jaren geleden
MZ.js d8e79ace03 index commit 3 jaren geleden
NA.js d8e79ace03 index commit 3 jaren geleden
NC.js d8e79ace03 index commit 3 jaren geleden
NE.js d8e79ace03 index commit 3 jaren geleden
NF.js d8e79ace03 index commit 3 jaren geleden
NG.js d8e79ace03 index commit 3 jaren geleden
NI.js d8e79ace03 index commit 3 jaren geleden
NL.js d8e79ace03 index commit 3 jaren geleden
NO.js d8e79ace03 index commit 3 jaren geleden
NP.js d8e79ace03 index commit 3 jaren geleden
NR.js d8e79ace03 index commit 3 jaren geleden
NU.js d8e79ace03 index commit 3 jaren geleden
NZ.js d8e79ace03 index commit 3 jaren geleden
OM.js d8e79ace03 index commit 3 jaren geleden
PA.js d8e79ace03 index commit 3 jaren geleden
PE.js d8e79ace03 index commit 3 jaren geleden
PF.js d8e79ace03 index commit 3 jaren geleden
PG.js d8e79ace03 index commit 3 jaren geleden
PH.js d8e79ace03 index commit 3 jaren geleden
PK.js d8e79ace03 index commit 3 jaren geleden
PL.js d8e79ace03 index commit 3 jaren geleden
PM.js d8e79ace03 index commit 3 jaren geleden
PN.js d8e79ace03 index commit 3 jaren geleden
PR.js d8e79ace03 index commit 3 jaren geleden
PS.js d8e79ace03 index commit 3 jaren geleden
PT.js d8e79ace03 index commit 3 jaren geleden
PW.js d8e79ace03 index commit 3 jaren geleden
PY.js d8e79ace03 index commit 3 jaren geleden
QA.js d8e79ace03 index commit 3 jaren geleden
RE.js d8e79ace03 index commit 3 jaren geleden
RO.js d8e79ace03 index commit 3 jaren geleden
RS.js d8e79ace03 index commit 3 jaren geleden
RU.js d8e79ace03 index commit 3 jaren geleden
RW.js d8e79ace03 index commit 3 jaren geleden
SA.js d8e79ace03 index commit 3 jaren geleden
SB.js d8e79ace03 index commit 3 jaren geleden
SC.js d8e79ace03 index commit 3 jaren geleden
SD.js d8e79ace03 index commit 3 jaren geleden
SE.js d8e79ace03 index commit 3 jaren geleden
SG.js d8e79ace03 index commit 3 jaren geleden
SH.js d8e79ace03 index commit 3 jaren geleden
SI.js d8e79ace03 index commit 3 jaren geleden
SK.js d8e79ace03 index commit 3 jaren geleden
SL.js d8e79ace03 index commit 3 jaren geleden
SM.js d8e79ace03 index commit 3 jaren geleden
SN.js d8e79ace03 index commit 3 jaren geleden
SO.js d8e79ace03 index commit 3 jaren geleden
SR.js d8e79ace03 index commit 3 jaren geleden
ST.js d8e79ace03 index commit 3 jaren geleden
SV.js d8e79ace03 index commit 3 jaren geleden
SY.js d8e79ace03 index commit 3 jaren geleden
SZ.js d8e79ace03 index commit 3 jaren geleden
TC.js d8e79ace03 index commit 3 jaren geleden
TD.js d8e79ace03 index commit 3 jaren geleden
TG.js d8e79ace03 index commit 3 jaren geleden
TH.js d8e79ace03 index commit 3 jaren geleden
TJ.js d8e79ace03 index commit 3 jaren geleden
TK.js d8e79ace03 index commit 3 jaren geleden
TL.js d8e79ace03 index commit 3 jaren geleden
TM.js d8e79ace03 index commit 3 jaren geleden
TN.js d8e79ace03 index commit 3 jaren geleden
TO.js d8e79ace03 index commit 3 jaren geleden
TR.js d8e79ace03 index commit 3 jaren geleden
TT.js d8e79ace03 index commit 3 jaren geleden
TV.js d8e79ace03 index commit 3 jaren geleden
TW.js d8e79ace03 index commit 3 jaren geleden
TZ.js d8e79ace03 index commit 3 jaren geleden
UA.js d8e79ace03 index commit 3 jaren geleden
UG.js d8e79ace03 index commit 3 jaren geleden
US.js d8e79ace03 index commit 3 jaren geleden
UY.js d8e79ace03 index commit 3 jaren geleden
UZ.js d8e79ace03 index commit 3 jaren geleden
VA.js d8e79ace03 index commit 3 jaren geleden
VC.js d8e79ace03 index commit 3 jaren geleden
VE.js d8e79ace03 index commit 3 jaren geleden
VG.js d8e79ace03 index commit 3 jaren geleden
VI.js d8e79ace03 index commit 3 jaren geleden
VN.js d8e79ace03 index commit 3 jaren geleden
VU.js d8e79ace03 index commit 3 jaren geleden
WF.js d8e79ace03 index commit 3 jaren geleden
WS.js d8e79ace03 index commit 3 jaren geleden
YE.js d8e79ace03 index commit 3 jaren geleden
YT.js d8e79ace03 index commit 3 jaren geleden
ZA.js d8e79ace03 index commit 3 jaren geleden
ZM.js d8e79ace03 index commit 3 jaren geleden
ZW.js d8e79ace03 index commit 3 jaren geleden
alt-af.js d8e79ace03 index commit 3 jaren geleden
alt-an.js d8e79ace03 index commit 3 jaren geleden
alt-as.js d8e79ace03 index commit 3 jaren geleden
alt-eu.js d8e79ace03 index commit 3 jaren geleden
alt-na.js d8e79ace03 index commit 3 jaren geleden
alt-oc.js d8e79ace03 index commit 3 jaren geleden
alt-sa.js d8e79ace03 index commit 3 jaren geleden
alt-ww.js d8e79ace03 index commit 3 jaren geleden
tum/whitesports - Gogs: Simplico Git Service

暫無描述

class-wp-rest-pattern-directory-controller.php 10KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345
  1. <?php
  2. /**
  3. * Block Pattern Directory REST API: WP_REST_Pattern_Directory_Controller class
  4. *
  5. * @package WordPress
  6. * @subpackage REST_API
  7. * @since 5.8.0
  8. */
  9. /**
  10. * Controller which provides REST endpoint for block patterns.
  11. *
  12. * This simply proxies the endpoint at http://api.wordpress.org/patterns/1.0/. That isn't necessary for
  13. * functionality, but is desired for privacy. It prevents api.wordpress.org from knowing the user's IP address.
  14. *
  15. * @since 5.8.0
  16. *
  17. * @see WP_REST_Controller
  18. */
  19. class WP_REST_Pattern_Directory_Controller extends WP_REST_Controller {
  20. /**
  21. * Constructs the controller.
  22. *
  23. * @since 5.8.0
  24. */
  25. public function __construct() {
  26. $this->namespace = 'wp/v2';
  27. $this->rest_base = 'pattern-directory';
  28. }
  29. /**
  30. * Registers the necessary REST API routes.
  31. *
  32. * @since 5.8.0
  33. */
  34. public function register_routes() {
  35. register_rest_route(
  36. $this->namespace,
  37. '/' . $this->rest_base . '/patterns',
  38. array(
  39. array(
  40. 'methods' => WP_REST_Server::READABLE,
  41. 'callback' => array( $this, 'get_items' ),
  42. 'permission_callback' => array( $this, 'get_items_permissions_check' ),
  43. 'args' => $this->get_collection_params(),
  44. ),
  45. 'schema' => array( $this, 'get_public_item_schema' ),
  46. )
  47. );
  48. }
  49. /**
  50. * Checks whether a given request has permission to view the local pattern directory.
  51. *
  52. * @since 5.8.0
  53. *
  54. * @param WP_REST_Request $request Full details about the request.
  55. * @return true|WP_Error True if the request has permission, WP_Error object otherwise.
  56. */
  57. public function get_items_permissions_check( $request ) {
  58. if ( current_user_can( 'edit_posts' ) ) {
  59. return true;
  60. }
  61. foreach ( get_post_types( array( 'show_in_rest' => true ), 'objects' ) as $post_type ) {
  62. if ( current_user_can( $post_type->cap->edit_posts ) ) {
  63. return true;
  64. }
  65. }
  66. return new WP_Error(
  67. 'rest_pattern_directory_cannot_view',
  68. __( 'Sorry, you are not allowed to browse the local block pattern directory.' ),
  69. array( 'status' => rest_authorization_required_code() )
  70. );
  71. }
  72. /**
  73. * Search and retrieve block patterns metadata
  74. *
  75. * @since 5.8.0
  76. *
  77. * @param WP_REST_Request $request Full details about the request.
  78. * @return WP_REST_Response|WP_Error Response object on success, or WP_Error object on failure.
  79. */
  80. public function get_items( $request ) {
  81. /*
  82. * Include an unmodified `$wp_version`, so the API can craft a response that's tailored to
  83. * it. Some plugins modify the version in a misguided attempt to improve security by
  84. * obscuring the version, which can cause invalid requests.
  85. */
  86. require ABSPATH . WPINC . '/version.php';
  87. $query_args = array(
  88. 'locale' => get_user_locale(),
  89. 'wp-version' => $wp_version,
  90. );
  91. $category_id = $request['category'];
  92. $keyword_id = $request['keyword'];
  93. $search_term = $request['search'];
  94. if ( $category_id ) {
  95. $query_args['pattern-categories'] = $category_id;
  96. }
  97. if ( $keyword_id ) {
  98. $query_args['pattern-keywords'] = $keyword_id;
  99. }
  100. if ( $search_term ) {
  101. $query_args['search'] = $search_term;
  102. }
  103. /*
  104. * Include a hash of the query args, so that different requests are stored in
  105. * separate caches.
  106. *
  107. * MD5 is chosen for its speed, low-collision rate, universal availability, and to stay
  108. * under the character limit for `_site_transient_timeout_{...}` keys.
  109. *
  110. * @link https://stackoverflow.com/questions/3665247/fastest-hash-for-non-cryptographic-uses
  111. */
  112. $transient_key = 'wp_remote_block_patterns_' . md5( implode( '-', $query_args ) );
  113. /*
  114. * Use network-wide transient to improve performance. The locale is the only site
  115. * configuration that affects the response, and it's included in the transient key.
  116. */
  117. $raw_patterns = get_site_transient( $transient_key );
  118. if ( ! $raw_patterns ) {
  119. $api_url = add_query_arg(
  120. array_map( 'rawurlencode', $query_args ),
  121. 'http://api.wordpress.org/patterns/1.0/'
  122. );
  123. if ( wp_http_supports( array( 'ssl' ) ) ) {
  124. $api_url = set_url_scheme( $api_url, 'https' );
  125. }
  126. /*
  127. * Default to a short TTL, to mitigate cache stampedes on high-traffic sites.
  128. * This assumes that most errors will be short-lived, e.g., packet loss that causes the
  129. * first request to fail, but a follow-up one will succeed. The value should be high
  130. * enough to avoid stampedes, but low enough to not interfere with users manually
  131. * re-trying a failed request.
  132. */
  133. $cache_ttl = 5;
  134. $wporg_response = wp_remote_get( $api_url );
  135. $raw_patterns = json_decode( wp_remote_retrieve_body( $wporg_response ) );
  136. if ( is_wp_error( $wporg_response ) ) {
  137. $raw_patterns = $wporg_response;
  138. } elseif ( ! is_array( $raw_patterns ) ) {
  139. // HTTP request succeeded, but response data is invalid.
  140. $raw_patterns = new WP_Error(
  141. 'pattern_api_failed',
  142. sprintf(
  143. /* translators: %s: Support forums URL. */
  144. __( 'An unexpected error occurred. Something may be wrong with WordPress.org or this server&#8217;s configuration. If you continue to have problems, please try the <a href="%s">support forums</a>.' ),
  145. __( 'https://wordpress.org/support/forums/' )
  146. ),
  147. array(
  148. 'response' => wp_remote_retrieve_body( $wporg_response ),
  149. )
  150. );
  151. } else {
  152. // Response has valid data.
  153. $cache_ttl = HOUR_IN_SECONDS;
  154. }
  155. set_site_transient( $transient_key, $raw_patterns, $cache_ttl );
  156. }
  157. if ( is_wp_error( $raw_patterns ) ) {
  158. $raw_patterns->add_data( array( 'status' => 500 ) );
  159. return $raw_patterns;
  160. }
  161. $response = array();
  162. if ( $raw_patterns ) {
  163. foreach ( $raw_patterns as $pattern ) {
  164. $response[] = $this->prepare_response_for_collection(
  165. $this->prepare_item_for_response( $pattern, $request )
  166. );
  167. }
  168. }
  169. return new WP_REST_Response( $response );
  170. }
  171. /**
  172. * Prepare a raw pattern before it's output in an API response.
  173. *
  174. * @since 5.8.0
  175. *
  176. * @param object $raw_pattern A pattern from api.wordpress.org, before any changes.
  177. * @param WP_REST_Request $request Request object.
  178. * @return WP_REST_Response
  179. */
  180. public function prepare_item_for_response( $raw_pattern, $request ) {
  181. $prepared_pattern = array(
  182. 'id' => absint( $raw_pattern->id ),
  183. 'title' => sanitize_text_field( $raw_pattern->title->rendered ),
  184. 'content' => wp_kses_post( $raw_pattern->pattern_content ),
  185. 'categories' => array_map( 'sanitize_title', $raw_pattern->category_slugs ),
  186. 'keywords' => array_map( 'sanitize_title', $raw_pattern->keyword_slugs ),
  187. 'description' => sanitize_text_field( $raw_pattern->meta->wpop_description ),
  188. 'viewport_width' => absint( $raw_pattern->meta->wpop_viewport_width ),
  189. );
  190. $prepared_pattern = $this->add_additional_fields_to_object( $prepared_pattern, $request );
  191. $response = new WP_REST_Response( $prepared_pattern );
  192. /**
  193. * Filters the REST API response for a pattern.
  194. *
  195. * @since 5.8.0
  196. *
  197. * @param WP_REST_Response $response The response object.
  198. * @param object $raw_pattern The unprepared pattern.
  199. * @param WP_REST_Request $request The request object.
  200. */
  201. return apply_filters( 'rest_prepare_block_pattern', $response, $raw_pattern, $request );
  202. }
  203. /**
  204. * Retrieves the pattern's schema, conforming to JSON Schema.
  205. *
  206. * @since 5.8.0
  207. *
  208. * @return array Item schema data.
  209. */
  210. public function get_item_schema() {
  211. if ( $this->schema ) {
  212. return $this->add_additional_fields_schema( $this->schema );
  213. }
  214. $this->schema = array(
  215. '$schema' => 'http://json-schema.org/draft-04/schema#',
  216. 'title' => 'pattern-directory-item',
  217. 'type' => 'object',
  218. 'properties' => array(
  219. 'id' => array(
  220. 'description' => __( 'The pattern ID.' ),
  221. 'type' => 'integer',
  222. 'minimum' => 1,
  223. 'context' => array( 'view', 'embed' ),
  224. ),
  225. 'title' => array(
  226. 'description' => __( 'The pattern title, in human readable format.' ),
  227. 'type' => 'string',
  228. 'minLength' => 1,
  229. 'context' => array( 'view', 'embed' ),
  230. ),
  231. 'content' => array(
  232. 'description' => __( 'The pattern content.' ),
  233. 'type' => 'string',
  234. 'minLength' => 1,
  235. 'context' => array( 'view', 'embed' ),
  236. ),
  237. 'categories' => array(
  238. 'description' => __( "The pattern's category slugs." ),
  239. 'type' => 'array',
  240. 'uniqueItems' => true,
  241. 'items' => array( 'type' => 'string' ),
  242. 'context' => array( 'view', 'embed' ),
  243. ),
  244. 'keywords' => array(
  245. 'description' => __( "The pattern's keyword slugs." ),
  246. 'type' => 'array',
  247. 'uniqueItems' => true,
  248. 'items' => array( 'type' => 'string' ),
  249. 'context' => array( 'view', 'embed' ),
  250. ),
  251. 'description' => array(
  252. 'description' => __( 'A description of the pattern.' ),
  253. 'type' => 'string',
  254. 'minLength' => 1,
  255. 'context' => array( 'view', 'embed' ),
  256. ),
  257. 'viewport_width' => array(
  258. 'description' => __( 'The preferred width of the viewport when previewing a pattern, in pixels.' ),
  259. 'type' => 'integer',
  260. 'context' => array( 'view', 'embed' ),
  261. ),
  262. ),
  263. );
  264. return $this->add_additional_fields_schema( $this->schema );
  265. }
  266. /**
  267. * Retrieves the search params for the patterns collection.
  268. *
  269. * @since 5.8.0
  270. *
  271. * @return array Collection parameters.
  272. */
  273. public function get_collection_params() {
  274. $query_params = parent::get_collection_params();
  275. // Pagination is not supported.
  276. unset( $query_params['page'] );
  277. unset( $query_params['per_page'] );
  278. $query_params['search']['minLength'] = 1;
  279. $query_params['context']['default'] = 'view';
  280. $query_params['category'] = array(
  281. 'description' => __( 'Limit results to those matching a category ID.' ),
  282. 'type' => 'integer',
  283. 'minimum' => 1,
  284. );
  285. $query_params['keyword'] = array(
  286. 'description' => __( 'Limit results to those matching a keyword ID.' ),
  287. 'type' => 'integer',
  288. 'minimum' => 1,
  289. );
  290. /**
  291. * Filter collection parameters for the pattern directory controller.
  292. *
  293. * @since 5.8.0
  294. *
  295. * @param array $query_params JSON Schema-formatted collection parameters.
  296. */
  297. return apply_filters( 'rest_pattern_directory_collection_params', $query_params );
  298. }
  299. }