@automattic/newspack-blocks 1.37.0 → 1.48.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (292) hide show
  1. package/.cache/babel/00255e6096be9e31ec354db849dfefaa.json.gz +0 -0
  2. package/.cache/babel/0265bee20d709ac92f56456637727f4b.json.gz +0 -0
  3. package/.cache/babel/02986ba19dc461a152ea1c45f3f36a27.json.gz +0 -0
  4. package/.cache/babel/06a1700c1a4a989fc7886c86bf6223f7.json.gz +0 -0
  5. package/.cache/babel/07169c73863508b392f15022920bd0b6.json.gz +0 -0
  6. package/.cache/babel/0a5083e561829e3884cb5c71388adc3f.json.gz +0 -0
  7. package/.cache/babel/0a713997b6e4f45849ed6a4bff79cca5.json.gz +0 -0
  8. package/.cache/babel/0a9506bf649ffbe854e75459cf6b8972.json.gz +0 -0
  9. package/.cache/babel/0c12c4398bbbf2d771b13dd1d0e64097.json.gz +0 -0
  10. package/.cache/babel/0f8c18da204f4cc2777ca3191f10c309.json.gz +0 -0
  11. package/.cache/babel/0fced15ed787cc4239bb53c1d12892e6.json.gz +0 -0
  12. package/.cache/babel/10faf7c74a89e9aa4d8b9528a654913e.json.gz +0 -0
  13. package/.cache/babel/1353b411b65a123b5dc35012db11aa1d.json.gz +0 -0
  14. package/.cache/babel/1729336f326db1cf54b9c1671dc5e36c.json.gz +0 -0
  15. package/.cache/babel/17a433ab631a32d0712f3f75cf85ea99.json.gz +0 -0
  16. package/.cache/babel/1948e72d907f681ff771881ad6800ee1.json.gz +0 -0
  17. package/.cache/babel/1ab4bf44aa14d2eb7e6911900a3b2c12.json.gz +0 -0
  18. package/.cache/babel/1decfd137cac87a75bd83ffbd39c9106.json.gz +0 -0
  19. package/.cache/babel/2143ceff6d186bc13bc902e0f1f33dbf.json.gz +0 -0
  20. package/.cache/babel/23c63332718e167968a7c2a8a5f730eb.json.gz +0 -0
  21. package/.cache/babel/24bf53676e12293cbf88d01e649fd167.json.gz +0 -0
  22. package/.cache/babel/26ba0bb46844575022e54a8819fbf405.json.gz +0 -0
  23. package/.cache/babel/281ca171ce8947f87f574df11059e00b.json.gz +0 -0
  24. package/.cache/babel/28700b83434e4dbfb9a20d7ec0a7e7a4.json.gz +0 -0
  25. package/.cache/babel/29cf8eeea8630ade027e34459f2e49ee.json.gz +0 -0
  26. package/.cache/babel/2b0dd254a46223a93e6259d2b797a7e7.json.gz +0 -0
  27. package/.cache/babel/2da6786ede3ddda4c86eeac524a6a796.json.gz +0 -0
  28. package/.cache/babel/2e7ce10fdee94274b48d528f94c32b34.json.gz +0 -0
  29. package/.cache/babel/2f93fed1706a40d82122281cc3677074.json.gz +0 -0
  30. package/.cache/babel/3a59b710e9745ef93148d6d74ee7d16f.json.gz +0 -0
  31. package/.cache/babel/3b2c440027c793c8f7978d7622cbfca0.json.gz +0 -0
  32. package/.cache/babel/3ca939ace4af88e266942d93837ab37a.json.gz +0 -0
  33. package/.cache/babel/3e671670c4d395cd1804ef4be31955e4.json.gz +0 -0
  34. package/.cache/babel/3e69fe002d9973c0030152a51da9477a.json.gz +0 -0
  35. package/.cache/babel/3f5f8ea603fd57850c6683c750fe53d8.json.gz +0 -0
  36. package/.cache/babel/41abaaadb68b0657a95fa0c356873def.json.gz +0 -0
  37. package/.cache/babel/421ac952d6b472ba18e1cb95ef65f42a.json.gz +0 -0
  38. package/.cache/babel/424185dd50e91d8dee5fdae43086010e.json.gz +0 -0
  39. package/.cache/babel/427a6423ebde76bcb488747127e47351.json.gz +0 -0
  40. package/.cache/babel/43e800659f23430a181fb4fc328eb6ef.json.gz +0 -0
  41. package/.cache/babel/469651017a2b6f3b9f63fda034974b3a.json.gz +0 -0
  42. package/.cache/babel/480d26447b7ee019a37e4e18422403e9.json.gz +0 -0
  43. package/.cache/babel/4b58fad313d90a4c1577a2766e6c924c.json.gz +0 -0
  44. package/.cache/babel/4d2d42fea63650192d1a3a5648b621c5.json.gz +0 -0
  45. package/.cache/babel/4d8c26a76e77fa64d01f30a5f2d62f85.json.gz +0 -0
  46. package/.cache/babel/4f606ce6656565507a74aaac8dc21eea.json.gz +0 -0
  47. package/.cache/babel/505f37592f4c601ccdc1581ca89d9009.json.gz +0 -0
  48. package/.cache/babel/50aaf34aa54b2cd3058518e42850bb62.json.gz +0 -0
  49. package/.cache/babel/51fbf389462feb111228ba7ec64c631d.json.gz +0 -0
  50. package/.cache/babel/51fc90ae5fe129a095172032f304dc2c.json.gz +0 -0
  51. package/.cache/babel/53dbf5484c5601528c2fd8d7fe728b78.json.gz +0 -0
  52. package/.cache/babel/58e4535574062eb2d8fa56d002e7190d.json.gz +0 -0
  53. package/.cache/babel/5aa5e8d1492938c62999de022c4b220e.json.gz +0 -0
  54. package/.cache/babel/5d64e475284e52c104df17e26066b17b.json.gz +0 -0
  55. package/.cache/babel/6333c664d69f13036f42bcf575c8e65d.json.gz +0 -0
  56. package/.cache/babel/635c439786b8522888342779b28ee9ee.json.gz +0 -0
  57. package/.cache/babel/648cffdd5ec4a2446f8935a17b98080b.json.gz +0 -0
  58. package/.cache/babel/64b0dd478e6f2dd51de5ee20e311aee7.json.gz +0 -0
  59. package/.cache/babel/6531721abbc0b3906b28b268ed7914af.json.gz +0 -0
  60. package/.cache/babel/66bf5585c7901a76c7d4014fa9ffed40.json.gz +0 -0
  61. package/.cache/babel/6ef313cb6d3a59f73a6b78e1a729fb13.json.gz +0 -0
  62. package/.cache/babel/6f14eed506421f15710d3dfafe3dcd93.json.gz +0 -0
  63. package/.cache/babel/70f6c01d8c6bc3efc41c97eaf49f7617.json.gz +0 -0
  64. package/.cache/babel/72321dde68f0bb9c334d90d6f4584be8.json.gz +0 -0
  65. package/.cache/babel/76c815fab58595f57e01af6591791d57.json.gz +0 -0
  66. package/.cache/babel/7c10f4d554daa8efe1e0a4457fb6d27b.json.gz +0 -0
  67. package/.cache/babel/7dffccddd9780ab37fb79f809947c2cd.json.gz +0 -0
  68. package/.cache/babel/7e5162e3319cd5d6fca6c0db0516aaeb.json.gz +0 -0
  69. package/.cache/babel/803192c922f7d419648bab7e1201b22e.json.gz +0 -0
  70. package/.cache/babel/81f3f0f896d29cdf88f8543dedb77787.json.gz +0 -0
  71. package/.cache/babel/84c019d3d643195fb37d08110f15f8c9.json.gz +0 -0
  72. package/.cache/babel/853c31db7c4351f2f36d1021c667224d.json.gz +0 -0
  73. package/.cache/babel/88ec99735ea4f314937736f04360ff8c.json.gz +0 -0
  74. package/.cache/babel/8959ab8fcfa783cb56e9418b99c0951c.json.gz +0 -0
  75. package/.cache/babel/8b9624d721f8706682e33fe1853c8287.json.gz +0 -0
  76. package/.cache/babel/8de5c373bbc4b6fbeec373d582935887.json.gz +0 -0
  77. package/.cache/babel/8f24517cff634d2e91c19e51be8816cc.json.gz +0 -0
  78. package/.cache/babel/901e1bb823eca196b594baa35a35a81c.json.gz +0 -0
  79. package/.cache/babel/90dbc666ff9fa3b88f305fe90a9917bf.json.gz +0 -0
  80. package/.cache/babel/91b62dfd9475df7a39dc08fbd43847f9.json.gz +0 -0
  81. package/.cache/babel/956daf27323e3b87bf8bf9bbf58881ed.json.gz +0 -0
  82. package/.cache/babel/959e9b81103c539a9d85ac60955451b9.json.gz +0 -0
  83. package/.cache/babel/963b1e44be998c4dcc6845745c377369.json.gz +0 -0
  84. package/.cache/babel/966b41ac1317b3e03ca1e59f7eb57e8c.json.gz +0 -0
  85. package/.cache/babel/969d5992cc682e3b43761ef02c10b851.json.gz +0 -0
  86. package/.cache/babel/99df128bb528d0f95a56b311801d14c1.json.gz +0 -0
  87. package/.cache/babel/9b33e7d21f3fc4955a536a033cced71b.json.gz +0 -0
  88. package/.cache/babel/9c5ec84f77314a621c01ad77da7ccb58.json.gz +0 -0
  89. package/.cache/babel/9d325af12a88623602a5f8c2fce04847.json.gz +0 -0
  90. package/.cache/babel/a413e4d325543836d0800684bb26ed04.json.gz +0 -0
  91. package/.cache/babel/a5405f86b8d1485e62a125275507e60f.json.gz +0 -0
  92. package/.cache/babel/a7f7461321ca6fd4360df04bb894c106.json.gz +0 -0
  93. package/.cache/babel/a8a6812e1c7b65cc6d0bdebe2a35c8ca.json.gz +0 -0
  94. package/.cache/babel/aa89cfc4c88fcc465b8d74af824e7f6b.json.gz +0 -0
  95. package/.cache/babel/adbaeb5ddf5612b3dcd233a3f6f17bf2.json.gz +0 -0
  96. package/.cache/babel/ae18cd6ec42a3366c73435b62a9f5f70.json.gz +0 -0
  97. package/.cache/babel/aea149ee1ec6fa3ca7839c63f5edd78d.json.gz +0 -0
  98. package/.cache/babel/af1b34067a69854e109c0b0e45d90e43.json.gz +0 -0
  99. package/.cache/babel/b3a335ab950f502914013810b43b0ad5.json.gz +0 -0
  100. package/.cache/babel/b6cfba15cda3404d4b1041df448ed2b2.json.gz +0 -0
  101. package/.cache/babel/ba711530bd319618a0510d8361bebb45.json.gz +0 -0
  102. package/.cache/babel/ba77e682225df6126b636458055601d9.json.gz +0 -0
  103. package/.cache/babel/bab8189a74eee8d72702d1510b52b3b3.json.gz +0 -0
  104. package/.cache/babel/bd8741020db56bb5d999252812d1d717.json.gz +0 -0
  105. package/.cache/babel/beaa874c5e01203d9dbe23cb89405276.json.gz +0 -0
  106. package/.cache/babel/c196c9b8c21953c474acdaa9029b3cbf.json.gz +0 -0
  107. package/.cache/babel/c1e31e6c217023eb3d3fd5d3de486ac3.json.gz +0 -0
  108. package/.cache/babel/c3aa996443e7f377aa423bcc03ffc617.json.gz +0 -0
  109. package/.cache/babel/c481eae84d69b65405a44af442dbfea7.json.gz +0 -0
  110. package/.cache/babel/c4a817d6c4bf6eb3687ffccc5c2df801.json.gz +0 -0
  111. package/.cache/babel/c8b10cf6f706fb669d6dd7564385768d.json.gz +0 -0
  112. package/.cache/babel/caa2f98ba4af6eba0605543f690693c6.json.gz +0 -0
  113. package/.cache/babel/cada4b2cecb2c1fcc48b7a7ecda54907.json.gz +0 -0
  114. package/.cache/babel/d1bed5404789c427c32965ac6ecad0d9.json.gz +0 -0
  115. package/.cache/babel/d395e8c0a9c63680f2dcf90ca0e91d4a.json.gz +0 -0
  116. package/.cache/babel/d4672090e0dd9a73bfb00bd770b23643.json.gz +0 -0
  117. package/.cache/babel/d4c81f65fe6d78cdbdcf1ef901b7ba1b.json.gz +0 -0
  118. package/.cache/babel/d515ddc0797ea256ff7271507737e9ce.json.gz +0 -0
  119. package/.cache/babel/d742848d263503f79168f1a6b8a52097.json.gz +0 -0
  120. package/.cache/babel/d834b41d7028519ecd0cbc8c65d33dde.json.gz +0 -0
  121. package/.cache/babel/d9060b9162e7caf974db0b90b6134727.json.gz +0 -0
  122. package/.cache/babel/d946975b9beac51a39f600461e84b1b6.json.gz +0 -0
  123. package/.cache/babel/daf0af780cff2270b1ae0e4b97a5a4ab.json.gz +0 -0
  124. package/.cache/babel/db5215643b0737dc5245972a5c25f736.json.gz +0 -0
  125. package/.cache/babel/dd57b8d31664b147b9f1e3f5cd18cc2a.json.gz +0 -0
  126. package/.cache/babel/e0c78bdaae19f15e2dd4a773e842422b.json.gz +0 -0
  127. package/.cache/babel/e1a2c7e4fc3afe9cc6e03d60f4e4a23d.json.gz +0 -0
  128. package/.cache/babel/e210ff9aa99df972b8d81c4bda70f642.json.gz +0 -0
  129. package/.cache/babel/e259a73f84d5b92b94e6d094719264c3.json.gz +0 -0
  130. package/.cache/babel/e6ce03a9908c9c4dc2c723531f1073f6.json.gz +0 -0
  131. package/.cache/babel/e8a1501dd8e4b3389ecdc8f722622359.json.gz +0 -0
  132. package/.cache/babel/eb3bb371036da362c42db50248d0b180.json.gz +0 -0
  133. package/.cache/babel/eb854e03c810bdb969497b2a36119bfa.json.gz +0 -0
  134. package/.cache/babel/ec25bb53826070b7f301e64f02355b8c.json.gz +0 -0
  135. package/.cache/babel/edbaca20e4a65f850c3d8321c1945718.json.gz +0 -0
  136. package/.cache/babel/f059f1ca9e49d5c3e655d20339860dce.json.gz +0 -0
  137. package/.cache/babel/f24c559fb42ef906405966598baf5f80.json.gz +0 -0
  138. package/.cache/babel/f2f333c3c546ad711d722d782decd450.json.gz +0 -0
  139. package/.cache/babel/f42c854ce8f1dc1a6e6fe7c510b033a5.json.gz +0 -0
  140. package/.cache/babel/f5211608f22c2e12594eafdbc4e66aa5.json.gz +0 -0
  141. package/.cache/babel/f645b8c88a49718cd778e3595212d4eb.json.gz +0 -0
  142. package/.cache/babel/f66dda5c4e4e9d04eb6b7411fcb12a65.json.gz +0 -0
  143. package/.cache/babel/f9d5b6f3f5438342dba75c2ce6143eef.json.gz +0 -0
  144. package/.cache/babel/fc9c60ee1d2e8783ba4c08db5cf97d40.json.gz +0 -0
  145. package/.cache/babel/fd558798cea72d04fb826468a89d72aa.json.gz +0 -0
  146. package/.cache/babel/fe735cbd0f6e131e28d8b6eb1f39141b.json.gz +0 -0
  147. package/.eslintrc.js +3 -26
  148. package/.nvmrc +1 -0
  149. package/CHANGELOG.md +422 -0
  150. package/babel.config.js +6 -0
  151. package/block-list.json +1 -1
  152. package/composer.json +2 -2
  153. package/composer.lock +446 -161
  154. package/dist/author-list/view.asset.php +1 -0
  155. package/dist/author-list/view.css +1 -0
  156. package/dist/author-list/view.js +1 -0
  157. package/dist/author-list/view.rtl.css +1 -0
  158. package/dist/author-profile/view.asset.php +1 -0
  159. package/dist/author-profile/view.css +1 -0
  160. package/dist/author-profile/view.js +1 -0
  161. package/dist/author-profile/view.rtl.css +1 -0
  162. package/dist/block_styles.asset.php +1 -0
  163. package/dist/block_styles.css +1 -0
  164. package/dist/block_styles.js +1 -0
  165. package/dist/block_styles.rtl.css +1 -0
  166. package/dist/carousel/view.asset.php +1 -0
  167. package/dist/carousel/view.css +1 -0
  168. package/dist/carousel/view.js +1 -0
  169. package/dist/carousel/view.rtl.css +1 -0
  170. package/dist/donate/view.asset.php +1 -0
  171. package/dist/donate/view.css +1 -0
  172. package/dist/donate/view.js +1 -0
  173. package/dist/donate/view.rtl.css +1 -0
  174. package/dist/donateStreamlined.asset.php +1 -0
  175. package/dist/donateStreamlined.css +1 -0
  176. package/dist/donateStreamlined.js +1 -0
  177. package/dist/donateStreamlined.rtl.css +1 -0
  178. package/dist/editor.asset.php +1 -0
  179. package/dist/editor.css +1 -0
  180. package/dist/editor.js +41 -0
  181. package/dist/editor.rtl.css +1 -0
  182. package/dist/homepage-articles/view.asset.php +1 -0
  183. package/dist/homepage-articles/view.css +1 -0
  184. package/dist/homepage-articles/view.js +1 -0
  185. package/dist/homepage-articles/view.rtl.css +1 -0
  186. package/dist/iframe/view.asset.php +1 -0
  187. package/dist/iframe/view.css +1 -0
  188. package/dist/iframe/view.js +1 -0
  189. package/dist/iframe/view.rtl.css +1 -0
  190. package/includes/class-newspack-blocks-api.php +14 -69
  191. package/includes/class-newspack-blocks-patterns.php +4 -1
  192. package/includes/class-newspack-blocks.php +421 -95
  193. package/newspack-blocks.php +26 -2
  194. package/package.json +31 -129
  195. package/postcss.config.js +11 -0
  196. package/src/block-patterns/subscribe-2.php +1 -1
  197. package/src/block-patterns/subscribe-3.php +1 -1
  198. package/src/block-patterns/subscribe-7.php +12 -0
  199. package/src/block-patterns/subscribe-8.php +12 -0
  200. package/src/block-patterns/subscribe-9.php +12 -0
  201. package/src/block-styles/core/columns/editor.scss +5 -8
  202. package/src/block-styles/core/columns/view.scss +83 -42
  203. package/src/blocks/author-list/block.json +82 -0
  204. package/src/blocks/author-list/class-wp-rest-newspack-author-list-controller.php +387 -0
  205. package/src/blocks/author-list/edit.js +527 -0
  206. package/src/blocks/author-list/editor.js +7 -0
  207. package/src/blocks/author-list/editor.scss +1 -0
  208. package/src/blocks/author-list/index.js +45 -0
  209. package/src/blocks/author-list/view.js +5 -0
  210. package/src/blocks/author-list/view.php +175 -0
  211. package/src/blocks/author-list/view.scss +46 -0
  212. package/src/blocks/author-profile/block.json +8 -0
  213. package/src/blocks/author-profile/class-wp-rest-newspack-authors-controller.php +69 -14
  214. package/src/blocks/author-profile/edit.js +212 -189
  215. package/src/blocks/author-profile/editor.scss +1 -1
  216. package/src/blocks/author-profile/single-author.js +100 -0
  217. package/src/blocks/author-profile/view.php +38 -92
  218. package/src/blocks/author-profile/view.scss +120 -1
  219. package/src/blocks/carousel/create-swiper.js +14 -5
  220. package/src/blocks/carousel/edit.js +4 -2
  221. package/src/blocks/carousel/editor.scss +3 -12
  222. package/src/blocks/carousel/view.js +1 -1
  223. package/src/blocks/carousel/view.php +9 -5
  224. package/src/blocks/carousel/view.scss +29 -3
  225. package/src/blocks/donate/class-wp-rest-newspack-donate-controller.php +22 -24
  226. package/src/blocks/donate/edit.js +49 -42
  227. package/src/blocks/donate/editor.scss +27 -3
  228. package/src/blocks/donate/index.js +31 -4
  229. package/src/blocks/donate/streamlined/index.js +248 -0
  230. package/src/blocks/donate/streamlined/index.test.js +125 -0
  231. package/src/blocks/donate/streamlined/style.scss +324 -0
  232. package/src/blocks/donate/streamlined/utils.js +174 -0
  233. package/src/blocks/donate/streamlined/utils.test.js +18 -0
  234. package/src/blocks/donate/view.php +77 -36
  235. package/src/blocks/donate/view.scss +291 -0
  236. package/src/blocks/homepage-articles/block.json +8 -0
  237. package/src/blocks/homepage-articles/class-wp-rest-newspack-articles-controller.php +24 -78
  238. package/src/blocks/homepage-articles/edit.js +26 -0
  239. package/src/blocks/homepage-articles/store.js +11 -1
  240. package/src/blocks/homepage-articles/templates/article.php +31 -3
  241. package/src/blocks/homepage-articles/templates/articles-loop.php +6 -5
  242. package/src/blocks/homepage-articles/utils.js +11 -10
  243. package/src/blocks/homepage-articles/view.php +4 -1
  244. package/src/blocks/homepage-articles/view.scss +69 -24
  245. package/src/blocks/iframe/block.json +34 -0
  246. package/src/blocks/iframe/class-wp-rest-newspack-iframe-controller.php +345 -0
  247. package/src/blocks/iframe/edit.js +252 -0
  248. package/src/blocks/iframe/editor.js +7 -0
  249. package/src/blocks/iframe/editor.scss +84 -0
  250. package/src/blocks/iframe/icons.js +10 -0
  251. package/src/blocks/iframe/iframe-placeholder.js +180 -0
  252. package/src/blocks/iframe/index.js +48 -0
  253. package/src/blocks/iframe/view.js +5 -0
  254. package/src/blocks/iframe/view.php +130 -0
  255. package/src/blocks/iframe/view.scss +9 -0
  256. package/src/blocks/video-playlist/view.php +4 -3
  257. package/src/components/query-controls.js +5 -4
  258. package/src/setup/editor.js +0 -1
  259. package/src/shared/js/utils.js +1 -1
  260. package/src/templates/author-profile-card.php +99 -0
  261. package/vendor/autoload.php +7 -0
  262. package/vendor/composer/ClassLoader.php +572 -0
  263. package/vendor/composer/InstalledVersions.php +350 -0
  264. package/vendor/composer/LICENSE +21 -0
  265. package/vendor/composer/autoload_classmap.php +10 -0
  266. package/vendor/composer/autoload_namespaces.php +9 -0
  267. package/vendor/composer/autoload_psr4.php +9 -0
  268. package/vendor/composer/autoload_real.php +55 -0
  269. package/vendor/composer/autoload_static.php +20 -0
  270. package/vendor/composer/installed.json +5 -0
  271. package/vendor/composer/installed.php +23 -0
  272. package/webpack.config.js +2 -3
  273. package/.circleci/config.yml +0 -96
  274. package/.distignore +0 -36
  275. package/.editorconfig +0 -22
  276. package/.github/ISSUE_TEMPLATE/Bug_report.md +0 -21
  277. package/.github/ISSUE_TEMPLATE/Enhancement.md +0 -17
  278. package/.github/ISSUE_TEMPLATE/Feature_request.md +0 -17
  279. package/.github/PULL_REQUEST_TEMPLATE.md +0 -29
  280. package/.github/workflows/main.yml +0 -15
  281. package/.phpcs.xml.dist +0 -55
  282. package/.prettierrc +0 -10
  283. package/.stylelintrc +0 -21
  284. package/.travis.yml +0 -67
  285. package/phpunit.xml.dist +0 -16
  286. package/src/blocks/author-profile/shared.scss +0 -95
  287. package/src/blocks/donate/streamlined.js +0 -180
  288. package/src/blocks/donate/streamlined.scss +0 -124
  289. package/src/setup/public-path.js +0 -13
  290. package/src/setup/view.js +0 -4
  291. package/tests/bootstrap.php +0 -31
  292. package/tests/test-sample.php +0 -20
@@ -118,7 +118,10 @@ class Newspack_Blocks_Patterns {
118
118
  'subscribe-3',
119
119
  'subscribe-4',
120
120
  'subscribe-5',
121
- 'subscribe-6'
121
+ 'subscribe-6',
122
+ 'subscribe-7',
123
+ 'subscribe-8',
124
+ 'subscribe-9'
122
125
  );
123
126
  }
124
127
 
@@ -15,6 +15,32 @@ class Newspack_Blocks {
15
15
  */
16
16
  const DONATE_STREAMLINED_SCRIPT_HANDLE = 'newspack-blocks-donate-streamlined';
17
17
 
18
+ /**
19
+ * Regex pattern we can use to search for and remove custom SQL statements.
20
+ * Custom statements added by this class are wrapped by `newspack-blocks` comments.
21
+ */
22
+ const SQL_PATTERN = '/\/\* newspack-blocks \*\/(.|\n)*\/\* \/newspack-blocks \*\//';
23
+
24
+ /**
25
+ * Class property to store user IDs and CAP guest author names for building
26
+ * custom SQL statements. In order to allow a single WP_Query to filter by
27
+ * both WP users and CAP guest authors (a taxonomy), we need to directly
28
+ * modify the JOIN and WHERE clauses in the SQL query.
29
+ *
30
+ * If this property is false, then the custom statements will be stripped
31
+ * from all SQL clauses. If it's an array with `authors` and `coauthors`
32
+ * keys, the custom statements will be added to the SQL query.
33
+ *
34
+ * Example array:
35
+ * [
36
+ * 'authors' => [], // Array of numeric WP user IDs.
37
+ * 'coauthors' => [], // Array of CAP guest author name slugs.
38
+ * ]
39
+ *
40
+ * @var boolean|array
41
+ */
42
+ protected static $filter_clauses = false;
43
+
18
44
  /**
19
45
  * Add hooks and filters.
20
46
  */
@@ -23,6 +49,23 @@ class Newspack_Blocks {
23
49
  add_post_type_support( 'post', 'newspack_blocks' );
24
50
  add_post_type_support( 'page', 'newspack_blocks' );
25
51
  add_filter( 'script_loader_tag', [ __CLASS__, 'mark_view_script_as_amp_plus_allowed' ], 10, 2 );
52
+ add_action( 'jetpack_register_gutenberg_extensions', [ __CLASS__, 'disable_jetpack_donate' ], 99 );
53
+ add_filter( 'the_content', [ __CLASS__, 'hide_post_content_when_iframe_block_is_fullscreen' ] );
54
+ add_filter( 'posts_clauses', [ __CLASS__, 'filter_posts_clauses_when_co_authors' ], 999, 2 );
55
+ add_filter( 'posts_groupby', [ __CLASS__, 'group_by_post_id_filter' ], 999 );
56
+
57
+ /**
58
+ * Disable NextGEN's `C_NextGen_Shortcode_Manager`.
59
+ *
60
+ * The way it currently parses `the_content` conflicts with the REST API
61
+ * request to save a post containing a Homepage Posts block. This is due to
62
+ * how it uses output buffering through `ob_start()` on REST requests.
63
+ *
64
+ * @link https://plugins.trac.wordpress.org/browser/nextgen-gallery/tags/3.23/non_pope/class.nextgen_shortcode_manager.php#L193.
65
+ */
66
+ if ( ! defined( 'NGG_DISABLE_SHORTCODE_MANAGER' ) ) {
67
+ define( 'NGG_DISABLE_SHORTCODE_MANAGER', true ); // phpcs:ignore WordPress.NamingConventions.PrefixAllGlobals.NonPrefixedConstantFound
68
+ }
26
69
  }
27
70
 
28
71
  /**
@@ -38,6 +81,41 @@ class Newspack_Blocks {
38
81
  return $tag;
39
82
  }
40
83
 
84
+ /**
85
+ * Hide the post content when it contains an iframe block that is set to fullscreen mode.
86
+ *
87
+ * @param string $content post content from the_content hook.
88
+ * @return string the post content.
89
+ */
90
+ public static function hide_post_content_when_iframe_block_is_fullscreen( $content ) {
91
+ if ( has_block( 'newspack-blocks/iframe' ) ) {
92
+ $blocks = parse_blocks( get_post()->post_content );
93
+
94
+ foreach ( $blocks as $block ) {
95
+ if ( 'newspack-blocks/iframe' === $block['blockName']
96
+ && array_key_exists( 'isFullScreen', $block['attrs'] )
97
+ && $block['attrs']['isFullScreen']
98
+ ) {
99
+ // we don't need the post content since the iframe will be fullscreen.
100
+ $content = render_block( $block );
101
+
102
+ add_filter(
103
+ 'body_class',
104
+ function( $classes ) {
105
+ $classes[] = 'newspack-post-with-fullscreen-iframe';
106
+ return $classes;
107
+ }
108
+ );
109
+
110
+ // we don't need to show Newspack popups since the iframe will take over them.
111
+ add_filter( 'newspack_popups_assess_has_disabled_popups', '__return_true' );
112
+ }
113
+ }
114
+ }
115
+
116
+ return $content;
117
+ }
118
+
41
119
  /**
42
120
  * Gather dependencies and paths needed for script enqueuing.
43
121
  *
@@ -71,6 +149,39 @@ class Newspack_Blocks {
71
149
  return plugins_url( '/src/assets', NEWSPACK_BLOCKS__PLUGIN_FILE ) . '/stripe-badge.svg';
72
150
  }
73
151
 
152
+ /**
153
+ * Possible mimes for iframe archive source file.
154
+ */
155
+ public static function iframe_archive_accepted_file_mimes() {
156
+ return [ 'application/zip' => 'zip' ];
157
+ }
158
+
159
+ /**
160
+ * Possible mimes for iframe document source file.
161
+ */
162
+ public static function iframe_document_accepted_file_mimes() {
163
+ $mimes = get_allowed_mime_types();
164
+ return [
165
+ $mimes['pdf'] => 'pdf',
166
+ $mimes['doc'] => 'doc',
167
+ $mimes['docx'] => 'docx',
168
+ $mimes['xla|xls|xlt|xlw'] => 'xls',
169
+ $mimes['xlsx'] => 'xlsx',
170
+ $mimes['pot|pps|ppt'] => 'ppt',
171
+ $mimes['pptx'] => 'pptx',
172
+ ];
173
+ }
174
+
175
+ /**
176
+ * Possible mimes for iframe source file.
177
+ */
178
+ public static function iframe_accepted_file_mimes() {
179
+ return array_merge(
180
+ array_values( self::iframe_archive_accepted_file_mimes() ),
181
+ array_values( self::iframe_document_accepted_file_mimes() )
182
+ );
183
+ }
184
+
74
185
  /**
75
186
  * Enqueue block scripts and styles for editor.
76
187
  */
@@ -85,19 +196,29 @@ class Newspack_Blocks {
85
196
  $script_data['version'],
86
197
  true
87
198
  );
199
+
200
+ $localized_data = [
201
+ 'patterns' => self::get_patterns_for_post_type( get_post_type() ),
202
+ 'posts_rest_url' => rest_url( 'newspack-blocks/v1/newspack-blocks-posts' ),
203
+ 'specific_posts_rest_url' => rest_url( 'newspack-blocks/v1/newspack-blocks-specific-posts' ),
204
+ 'authors_rest_url' => rest_url( 'newspack-blocks/v1/authors' ),
205
+ 'assets_path' => plugins_url( '/src/assets', NEWSPACK_BLOCKS__PLUGIN_FILE ),
206
+ 'post_subtitle' => get_theme_support( 'post-subtitle' ),
207
+ 'is_rendering_streamlined_block' => self::is_rendering_streamlined_block(),
208
+ 'streamlined_block_stripe_badge' => self::streamlined_block_stripe_badge(),
209
+ 'iframe_accepted_file_mimes' => self::iframe_accepted_file_mimes(),
210
+ ];
211
+
212
+ if ( class_exists( 'WP_REST_Newspack_Author_List_Controller' ) ) {
213
+ $localized_data['can_use_cap'] = class_exists( 'CoAuthors_Guest_Authors' );
214
+ $author_list_controller = new WP_REST_Newspack_Author_List_Controller();
215
+ $localized_data['editable_roles'] = $author_list_controller->get_editable_roles();
216
+ }
217
+
88
218
  wp_localize_script(
89
219
  'newspack-blocks-editor',
90
220
  'newspack_blocks_data',
91
- [
92
- 'patterns' => self::get_patterns_for_post_type( get_post_type() ),
93
- 'posts_rest_url' => rest_url( 'newspack-blocks/v1/newspack-blocks-posts' ),
94
- 'specific_posts_rest_url' => rest_url( 'newspack-blocks/v1/newspack-blocks-specific-posts' ),
95
- 'authors_rest_url' => rest_url( 'newspack-blocks/v1/authors' ),
96
- 'assets_path' => plugins_url( '/src/assets', NEWSPACK_BLOCKS__PLUGIN_FILE ),
97
- 'post_subtitle' => get_theme_support( 'post-subtitle' ),
98
- 'is_rendering_streamlined_block' => self::is_rendering_streamlined_block(),
99
- 'streamlined_block_stripe_badge' => self::streamlined_block_stripe_badge(),
100
- ]
221
+ $localized_data
101
222
  );
102
223
 
103
224
  wp_set_script_translations(
@@ -259,9 +380,6 @@ class Newspack_Blocks {
259
380
  * @return bool True if AMP, false otherwise.
260
381
  */
261
382
  public static function is_amp() {
262
- if ( class_exists( 'Newspack\AMP_Enhancements' ) && method_exists( 'Newspack\AMP_Enhancements', 'should_use_amp_plus' ) && Newspack\AMP_Enhancements::should_use_amp_plus( 'gam' ) ) {
263
- return false;
264
- }
265
383
  if ( function_exists( 'is_amp_endpoint' ) && is_amp_endpoint() ) {
266
384
  return true;
267
385
  }
@@ -378,6 +496,9 @@ class Newspack_Blocks {
378
496
  * @return array
379
497
  */
380
498
  public static function build_articles_query( $attributes, $block_name ) {
499
+ // Reset author/CAP guest author SQL statements by default.
500
+ self::$filter_clauses = false;
501
+
381
502
  global $newspack_blocks_post_id;
382
503
  if ( ! $newspack_blocks_post_id ) {
383
504
  $newspack_blocks_post_id = array();
@@ -421,6 +542,7 @@ class Newspack_Blocks {
421
542
  'suppress_filters' => false,
422
543
  'ignore_sticky_posts' => true,
423
544
  'has_password' => false,
545
+ 'is_newspack_query' => true,
424
546
  );
425
547
  if ( $specific_mode && $specific_posts ) {
426
548
  $args['nopaging'] = true;
@@ -428,49 +550,112 @@ class Newspack_Blocks {
428
550
  $args['orderby'] = 'post__in';
429
551
  } else {
430
552
  $args['posts_per_page'] = $posts_to_show;
431
- if ( count( $newspack_blocks_all_specific_posts_ids ) ) {
432
- $args['post__not_in'] = $newspack_blocks_all_specific_posts_ids;
553
+
554
+ $show_rendered_posts = apply_filters( 'newspack_blocks_homepage_shown_rendered_posts', false );
555
+ if ( $show_rendered_posts ) {
556
+ $args['post__not_in'] = [ get_the_ID() ];
557
+ } else {
558
+ if ( count( $newspack_blocks_all_specific_posts_ids ) ) {
559
+ $args['post__not_in'] = $newspack_blocks_all_specific_posts_ids;
560
+ }
561
+ $args['post__not_in'] = array_merge(
562
+ $args['post__not_in'] ?? [],
563
+ array_keys( $newspack_blocks_post_id ),
564
+ get_the_ID() ? [ get_the_ID() ] : []
565
+ );
433
566
  }
434
- $args['post__not_in'] = array_merge(
435
- $args['post__not_in'] ?? [],
436
- array_keys( $newspack_blocks_post_id ),
437
- get_the_ID() ? [ get_the_ID() ] : []
438
- );
567
+
568
+ if ( $categories && count( $categories ) ) {
569
+ $args['category__in'] = $categories;
570
+ }
571
+ if ( $tags && count( $tags ) ) {
572
+ $args['tag__in'] = $tags;
573
+ }
574
+ if ( $tag_exclusions && count( $tag_exclusions ) ) {
575
+ $args['tag__not_in'] = $tag_exclusions;
576
+ }
577
+ if ( $category_exclusions && count( $category_exclusions ) ) {
578
+ $args['category__not_in'] = $category_exclusions;
579
+ }
580
+
439
581
  if ( $authors && count( $authors ) ) {
440
582
  $co_authors_names = [];
583
+ $author_names = [];
441
584
 
442
585
  if ( class_exists( 'CoAuthors_Guest_Authors' ) ) {
443
586
  $co_authors_guest_authors = new CoAuthors_Guest_Authors();
444
587
 
445
588
  foreach ( $authors as $index => $author_id ) {
589
+ // If the given ID is a guest author.
446
590
  $co_author = $co_authors_guest_authors->get_guest_author_by( 'id', $author_id );
447
591
  if ( $co_author ) {
592
+ if ( ! empty( $co_author->linked_account ) ) {
593
+ $linked_account = get_user_by( 'login', $co_author->linked_account );
594
+ if ( $linked_account ) {
595
+ $authors[] = $linked_account->ID;
596
+ }
597
+ }
448
598
  $co_authors_names[] = $co_author->user_nicename;
449
599
  unset( $authors[ $index ] );
600
+ } else {
601
+ // If the given ID is linked to a guest author.
602
+ $authors_controller = new WP_REST_Newspack_Authors_Controller();
603
+ $author_data = get_userdata( $author_id );
604
+ if ( $author_data ) {
605
+ $linked_guest_author = $authors_controller->get_linked_guest_author( $author_data->user_login );
606
+ if ( $linked_guest_author ) {
607
+ $guest_author_name = sanitize_title( $linked_guest_author->post_title );
608
+ if ( ! in_array( $guest_author_name, $co_authors_names, true ) ) {
609
+ $co_authors_names[] = $guest_author_name;
610
+ unset( $authors[ $index ] );
611
+ }
612
+ } else {
613
+ $author_names[] = $author_data->user_login;
614
+ }
615
+ }
450
616
  }
451
617
  }
452
618
  }
453
619
 
454
- if ( count( $co_authors_names ) ) {
455
- // look for authors and co-authors posts.
456
- self::filter_posts_clauses_when_co_authors( $authors, $co_authors_names );
457
- } else {
620
+ // Reset numeric indexes.
621
+ $authors = array_values( $authors );
622
+ if ( empty( $authors ) && count( $co_authors_names ) ) {
623
+ // Look for co-authors posts.
624
+ $args['tax_query'] = [ // phpcs:ignore WordPress.DB.SlowDBQuery.slow_db_query_tax_query
625
+ [
626
+ 'field' => 'name',
627
+ 'taxonomy' => 'author',
628
+ 'terms' => $co_authors_names,
629
+ ],
630
+ ];
631
+ } elseif ( empty( $co_authors_names ) && count( $authors ) ) {
458
632
  $args['author__in'] = $authors;
633
+
634
+ // Don't get any posts that are attributed to other CAP guest authors.
635
+ $args['tax_query'] = [ // phpcs:ignore WordPress.DB.SlowDBQuery.slow_db_query_tax_query
636
+ [
637
+ 'relation' => 'OR',
638
+ [
639
+ 'taxonomy' => 'author',
640
+ 'operator' => 'NOT EXISTS',
641
+ ],
642
+ [
643
+ 'field' => 'name',
644
+ 'taxonomy' => 'author',
645
+ 'terms' => $author_names,
646
+ ],
647
+ ],
648
+ ];
649
+ } else {
650
+ // The query contains both WP users and CAP guest authors. We need to filter the SQL query.
651
+ self::$filter_clauses = [
652
+ 'authors' => $authors,
653
+ 'coauthors' => $co_authors_names,
654
+ ];
459
655
  }
460
656
  }
461
- if ( $categories && count( $categories ) ) {
462
- $args['category__in'] = $categories;
463
- }
464
- if ( $tags && count( $tags ) ) {
465
- $args['tag__in'] = $tags;
466
- }
467
- if ( $tag_exclusions && count( $tag_exclusions ) ) {
468
- $args['tag__not_in'] = $tag_exclusions;
469
- }
470
- if ( $category_exclusions && count( $category_exclusions ) ) {
471
- $args['category__not_in'] = $category_exclusions;
472
- }
473
657
  }
658
+
474
659
  return $args;
475
660
  }
476
661
 
@@ -565,6 +750,15 @@ class Newspack_Blocks {
565
750
  $classes[] = 'type-' . $post_type;
566
751
  }
567
752
 
753
+ /**
754
+ * Filter the array of class names before applying them to the HTML.
755
+ *
756
+ * @param array $classes Array of term class names.
757
+ *
758
+ * @return array Filtered array of term class names.
759
+ */
760
+ $classes = apply_filters( 'newspack_blocks_term_classes', $classes );
761
+
568
762
  return implode( ' ', $classes );
569
763
  }
570
764
 
@@ -733,7 +927,15 @@ class Newspack_Blocks {
733
927
  /**
734
928
  * Closure for excerpt filtering that can be added and removed.
735
929
  *
736
- * @var newspack_blocks_excerpt_length_closure
930
+ * @var Closure
931
+ */
932
+ public static $newspack_blocks_excerpt_closure = null;
933
+
934
+ /**
935
+ * Closure for excerpt length filtering that can be added and removed.
936
+ *
937
+ * @var Closure
938
+ * @deprecated
737
939
  */
738
940
  public static $newspack_blocks_excerpt_length_closure = null;
739
941
 
@@ -752,6 +954,48 @@ class Newspack_Blocks {
752
954
  *
753
955
  * @param array $attributes The block's attributes.
754
956
  */
957
+ public static function filter_excerpt( $attributes ) {
958
+ if ( empty( $attributes['excerptLength'] ) || ! $attributes['showExcerpt'] ) {
959
+ return;
960
+ }
961
+
962
+ self::$newspack_blocks_excerpt_closure = function( $text = '', $post = null ) use ( $attributes ) {
963
+ $post = get_post( $post );
964
+ $text = $post->post_excerpt;
965
+ $raw_excerpt = $text;
966
+
967
+ if ( empty( $text ) ) {
968
+ $text = get_the_content( '', false, $post );
969
+ $text = strip_shortcodes( $text );
970
+ $text = excerpt_remove_blocks( $text );
971
+ }
972
+
973
+ /** This filter is documented in wp-includes/post-template.php */
974
+ $text = str_replace( ']]>', ']]>', $text );
975
+ $text = wp_trim_words( $text, $attributes['excerptLength'], static::more_excerpt() );
976
+
977
+ /** This filter is documented in wp-includes/post-template.php */
978
+ return apply_filters( 'wp_trim_excerpt', $text, $raw_excerpt ); // phpcs:ignore
979
+ };
980
+
981
+ add_filter( 'get_the_excerpt', self::$newspack_blocks_excerpt_closure, 11, 2 );
982
+ }
983
+
984
+ /**
985
+ * Remove excerpt filter after Homepage Posts block loop.
986
+ */
987
+ public static function remove_excerpt_filter() {
988
+ if ( static::$newspack_blocks_excerpt_closure ) {
989
+ remove_filter( 'get_the_excerpt', static::$newspack_blocks_excerpt_closure, 11 );
990
+ }
991
+ }
992
+
993
+ /**
994
+ * Filter for excerpt length.
995
+ *
996
+ * @deprecated
997
+ * @param array $attributes The block's attributes.
998
+ */
755
999
  public static function filter_excerpt_length( $attributes ) {
756
1000
  // If showing excerpt, filter the length using the block attribute.
757
1001
  if ( isset( $attributes['excerptLength'] ) && $attributes['showExcerpt'] ) {
@@ -771,6 +1015,8 @@ class Newspack_Blocks {
771
1015
 
772
1016
  /**
773
1017
  * Remove excerpt length filter after Homepage Posts block loop.
1018
+ *
1019
+ * @deprecated
774
1020
  */
775
1021
  public static function remove_excerpt_length_filter() {
776
1022
  if ( self::$newspack_blocks_excerpt_length_closure ) {
@@ -793,6 +1039,7 @@ class Newspack_Blocks {
793
1039
  /**
794
1040
  * Filter for excerpt ellipsis.
795
1041
  *
1042
+ * @deprecated
796
1043
  * @param array $attributes The block's attributes.
797
1044
  */
798
1045
  public static function filter_excerpt_more( $attributes ) {
@@ -804,87 +1051,121 @@ class Newspack_Blocks {
804
1051
 
805
1052
  /**
806
1053
  * Remove excerpt ellipsis filter after Homepage Posts block loop.
1054
+ *
1055
+ * @deprecated
807
1056
  */
808
1057
  public static function remove_excerpt_more_filter() {
809
1058
  remove_filter( 'excerpt_more', [ __CLASS__, 'more_excerpt' ], 999 );
810
1059
  }
811
1060
 
812
1061
  /**
813
- * Closure for posts clauses when we have co-authors can be added and removed.
1062
+ * Filter posts by authors and co-authors. If the query is filtering posts
1063
+ * by both WP users and CAP guest authors, the SQL clauses must be modified
1064
+ * directly so that the filtering can happen with a single SQL query.
814
1065
  *
815
- * @var $newspack_blocks_posts_clauses_when_co_authors_closure
1066
+ * @param string[] $clauses Associative array of the clauses for the query.
1067
+ * @param WP_Query $query The WP_Query instance (passed by reference).
816
1068
  */
817
- public static $newspack_blocks_posts_clauses_when_co_authors_closure = null;
1069
+ public static function filter_posts_clauses_when_co_authors( $clauses, $query ) {
1070
+ // Remove any lingering custom SQL statements.
1071
+ $clauses['join'] = preg_replace( self::SQL_PATTERN, '', $clauses['join'] );
1072
+ $clauses['where'] = preg_replace( self::SQL_PATTERN, '', $clauses['where'] );
1073
+ $is_newspack_query = isset( $query->query_vars['is_newspack_query'] ) && $query->query_vars['is_newspack_query'];
818
1074
 
819
- /**
820
- * Filter posts by authors and co-authors.
821
- *
822
- * @param int[] $authors_ids Authors IDs to filter with.
823
- * @param string[] $co_authors_names Co-authors names to filter with.
824
- */
825
- public static function filter_posts_clauses_when_co_authors( $authors_ids, $co_authors_names ) {
826
- self::$newspack_blocks_posts_clauses_when_co_authors_closure = add_filter(
827
- 'posts_clauses',
828
- function( $clauses ) use ( $authors_ids, $co_authors_names ) {
829
- global $wpdb;
1075
+ // If the query isn't coming from this plugin, or $filter_clauses lacks expected data.
1076
+ if (
1077
+ ! $is_newspack_query ||
1078
+ ! self::$filter_clauses ||
1079
+ ! isset( self::$filter_clauses['authors'] ) ||
1080
+ ! isset( self::$filter_clauses['coauthors'] )
1081
+ ) {
1082
+ return $clauses;
1083
+ }
830
1084
 
831
- // co-author tax query.
832
- $tax_query = array(
833
- array(
834
- 'taxonomy' => 'author',
835
- 'field' => 'name',
836
- 'terms' => $co_authors_names,
837
- ),
838
- );
1085
+ global $wpdb;
839
1086
 
840
- // Generate the tax query SQL.
841
- $tax_query = new WP_Tax_Query( $tax_query );
842
- $tax_query = $tax_query->get_sql( $wpdb->posts, 'ID' );
843
-
844
- // Generate the author query SQL.
845
- $csv = implode( ',', wp_parse_id_list( (array) $authors_ids ) );
846
- $authors = " {$wpdb->posts}.post_author IN ( $csv ) ";
847
-
848
- // Make sure the authors are set and the tax query is valid (doesn't contain 0 = 1).
849
- if ( false === strpos( $tax_query['where'], ' 0 = 1' ) ) {
850
- // Append to the current join/where parts.
851
- $clauses['join'] .= $tax_query['join'];
852
- $clauses['where'] .= sprintf(
853
- // The tax query SQL comes prepended with AND.
854
- ' AND ( %s ( 1=1 %s ) ) ',
855
- empty( $authors_ids ) ? '' : "$authors OR",
856
- $tax_query['where']
857
- );
858
- }
1087
+ $authors_ids = self::$filter_clauses['authors'];
1088
+ $co_authors_names = self::$filter_clauses['coauthors'];
859
1089
 
860
- return $clauses;
1090
+ // co-author tax query.
1091
+ $tax_query = [
1092
+ [
1093
+ 'taxonomy' => 'author',
1094
+ 'field' => 'name',
1095
+ 'terms' => $co_authors_names,
1096
+ ],
1097
+ ];
1098
+
1099
+ // Generate the tax query SQL.
1100
+ $tax_query = new WP_Tax_Query( $tax_query );
1101
+ $tax_query = $tax_query->get_sql( $wpdb->posts, 'ID' );
1102
+
1103
+ // Generate the author query SQL.
1104
+ $csv = implode( ',', wp_parse_id_list( (array) $authors_ids ) );
1105
+ $author_names = array_reduce(
1106
+ $authors_ids,
1107
+ function( $acc, $author_id ) {
1108
+ $author_data = get_userdata( $author_id );
1109
+ if ( $author_data ) {
1110
+ $acc[] = $author_data->user_login;
1111
+ }
1112
+ return $acc;
861
1113
  },
862
- 999
1114
+ []
1115
+ );
1116
+
1117
+ // If getting only WP users, we don't want to get posts attributed to CAP guest authors not linked to the given WP users.
1118
+ $exclude = new WP_Tax_Query(
1119
+ [
1120
+ 'relation' => 'OR',
1121
+ [
1122
+ 'taxonomy' => 'author',
1123
+ 'operator' => 'NOT EXISTS',
1124
+ ],
1125
+ [
1126
+ 'field' => 'name',
1127
+ 'taxonomy' => 'author',
1128
+ 'terms' => $author_names,
1129
+ ],
1130
+ ]
863
1131
  );
1132
+ $exclude = $exclude->get_sql( $wpdb->posts, 'ID' );
1133
+ $exclude = $exclude['where'];
1134
+ $authors = " ( {$wpdb->posts}.post_author IN ( $csv ) $exclude ) ";
1135
+
1136
+ // Make sure the authors are set, the tax query is valid (doesn't contain 0 = 1).
1137
+ if ( false === strpos( $tax_query['where'], ' 0 = 1' ) ) {
1138
+ // Append to the current join parts. The JOIN statment only needs to exist in the clause once.
1139
+ if ( false === strpos( $clauses['join'], $tax_query['join'] ) ) {
1140
+ $clauses['join'] .= '/* newspack-blocks */ ' . $tax_query['join'] . ' /* /newspack-blocks */';
1141
+ }
864
1142
 
865
- add_filter( 'posts_groupby', [ 'Newspack_Blocks', 'group_by_post_id_filter' ], 999 );
1143
+ $clauses['where'] .= sprintf(
1144
+ // The tax query SQL comes prepended with AND.
1145
+ '%s AND ( %s ( 1=1 %s ) ) %s',
1146
+ '/* newspack-blocks */',
1147
+ empty( $authors_ids ) ? '' : $authors . ' OR',
1148
+ $tax_query['where'],
1149
+ '/* /newspack-blocks */'
1150
+ );
1151
+ }
1152
+ return $clauses;
866
1153
  }
867
1154
 
868
1155
  /**
869
1156
  * Group by post ID filter, used when we join taxonomies while getting posts.
1157
+ *
1158
+ * @param string $groupby The GROUP BY clause of the query.
1159
+ * @return string The filtered GROUP BY clause.
870
1160
  */
871
- public static function group_by_post_id_filter() {
1161
+ public static function group_by_post_id_filter( $groupby ) {
872
1162
  global $wpdb;
873
- return "{$wpdb->posts}.ID ";
874
- }
875
1163
 
876
- /**
877
- * Remove posts clauses filter after Homepage Posts block loop.
878
- */
879
- public static function remove_filter_posts_clauses_when_co_authors_filter() {
880
- if ( self::$newspack_blocks_posts_clauses_when_co_authors_closure ) {
881
- remove_filter(
882
- 'posts_clauses',
883
- self::$newspack_blocks_posts_clauses_when_co_authors_closure,
884
- 999
885
- );
886
- remove_filter( 'posts_groupby', [ 'Newspack_Blocks', 'group_by_post_id_filter' ] );
1164
+ if ( self::$filter_clauses ) {
1165
+ return "{$wpdb->posts}.ID ";
887
1166
  }
1167
+
1168
+ return $groupby;
888
1169
  }
889
1170
 
890
1171
  /**
@@ -936,5 +1217,50 @@ class Newspack_Blocks {
936
1217
 
937
1218
  return wp_kses( $svg, $allowed_html );
938
1219
  }
1220
+
1221
+ /**
1222
+ * Disable Jetpack's donate block when using Newspack donations.
1223
+ */
1224
+ public static function disable_jetpack_donate() {
1225
+ // Do nothing if Jetpack's blocks or Newspack aren't being used.
1226
+ if ( ! class_exists( 'Jetpack_Gutenberg' ) || ! class_exists( 'Newspack' ) ) {
1227
+ return;
1228
+ }
1229
+
1230
+ // Allow Jetpack donations if Newspack donations isn't set up.
1231
+ $donate_settings = Newspack\Donations::get_donation_settings();
1232
+ if ( is_wp_error( $donate_settings ) || ! $donate_settings['created'] ) {
1233
+ return;
1234
+ }
1235
+
1236
+ // Tell Jetpack to mark the donations feature as unavailable.
1237
+ Jetpack_Gutenberg::set_extension_unavailable(
1238
+ 'jetpack/donations',
1239
+ esc_html__( 'Jetpack donations is disabled in favour of Newspack donations.', 'newspack-blocks' )
1240
+ );
1241
+ }
1242
+
1243
+ /**
1244
+ * Loads a template with given data in scope.
1245
+ *
1246
+ * @param string $template Name of the template to be included.
1247
+ * @param array $data Data to be passed into the template to be included.
1248
+ * @param string $path (Optional) Path to the folder containing the template.
1249
+ * @return string
1250
+ */
1251
+ public static function template_include( $template, $data = [], $path = NEWSPACK_BLOCKS__PLUGIN_DIR . 'src/templates/' ) {
1252
+ if ( ! strpos( $template, '.php' ) ) {
1253
+ $template = $template . '.php';
1254
+ }
1255
+ $path .= $template;
1256
+ if ( ! is_file( $path ) ) {
1257
+ return '';
1258
+ }
1259
+ ob_start();
1260
+ include $path;
1261
+ $contents = ob_get_contents();
1262
+ ob_end_clean();
1263
+ return $contents;
1264
+ }
939
1265
  }
940
1266
  Newspack_Blocks::init();