Advertisement
Guest User

Untitled

a guest
Jul 21st, 2019
139
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
text 15.33 KB | None | 0 0
  1. <?php
  2.  
  3. /**
  4. * Plugin Name: Daily Roundtable API
  5. * Plugin URI: https://app.codeable.io/tasks/new?preferredContractor=41145
  6. * Description: Exposes the daily roundtable to be fetched by other website
  7. * Version: 1.1.0
  8. * Author: Maciej Krawczyk
  9. * Author URI: https://app.codeable.io/tasks/new?preferredContractor=41145
  10. * License: MIT
  11.  
  12. **/
  13.  
  14. //exit if accessed directly
  15. defined('ABSPATH') or die();
  16.  
  17. class Jewish_Journal_Connector {
  18.  
  19. public function __construct() {
  20.  
  21. //full url to production site
  22. $production_url = 'https://roundtable.jewishjournal.com/';
  23.  
  24. //full url to development site
  25. $dev_url = 'https://dailyroundtabl.staging.wpengine.com/';
  26.  
  27. //this is used to determine whether production or dev url will be used
  28. $development_server_name = 'roundtable.jewishjournal.com';
  29.  
  30. //default to production url
  31. $this->jj_url = $production_url;
  32.  
  33. //if we are on the staging site, use the dev url
  34. if ($_SERVER['SERVER_NAME'] === $development_server_name)
  35. $this->jj_url = $dev_url;
  36.  
  37. $this->jj_url = trailingslashit( $this->jj_url );
  38.  
  39. add_action('wp_footer', array($this, 'widget_scripts'));
  40. add_action('wp_head', array($this, 'widget_styles'));
  41.  
  42. //output data for the first widget on Jewish Journal site
  43. add_action( 'wp_ajax_get-daily-roundtable', array($this, 'widget1_data_for_jj') );
  44. add_action( 'wp_ajax_nopriv_get-daily-roundtable', array($this, 'widget1_data_for_jj') );
  45.  
  46. //output data for the second widget on Jewish Journal site
  47. add_action( 'wp_ajax_get-daily-roundtable-takes', array($this, 'widget2_data_for_jj') );
  48. add_action( 'wp_ajax_nopriv_get-daily-roundtable-takes', array($this, 'widget2_data_for_jj') );
  49.  
  50. //fetch data from Jewish Journal for the widgets on the site
  51. add_action( 'wp_ajax_get-jj-widgets-data', array($this, 'widgets_ajax') );
  52. add_action( 'wp_ajax_nopriv_get-jj-widgets-data', array($this, 'widgets_ajax') );
  53.  
  54. //register widgets
  55. add_shortcode('jewish_journal_podcasts', array($this, 'podcast_widget'));
  56. add_shortcode('jewish_journal_print_issue', array($this, 'print_issue_widget'));
  57.  
  58. add_shortcode('jj_widgets_tmp', array($this, 'widgets_wrapper_shortcode'));
  59.  
  60.  
  61. $this->is_rendered = false;
  62.  
  63. }
  64.  
  65. //this is temporary - to display the widgets, you will most likely not need it later
  66. function widgets_wrapper_shortcode() {
  67.  
  68. ob_start();
  69.  
  70. ?><div id="mk-jj-widgets-wrapper">
  71.  
  72. <?php echo $this->podcast_widget(); ?>
  73. <?php echo $this->print_issue_widget(); ?>
  74.  
  75. </div><?php
  76.  
  77. return ob_get_clean();
  78.  
  79. }
  80.  
  81. function podcast_widget() {
  82.  
  83. $this->is_rendered = true;
  84.  
  85. ob_start();
  86.  
  87. ?>
  88.  
  89. <div id="podcasts">
  90. <div class="inner">
  91. <h4><a href="<?php echo $this->jj_url; ?>podcasts">Podcast Network</a></h4>
  92. <div id="podcast-wrapper"><!--podcasts_content--></div>
  93. </div>
  94. </div>
  95.  
  96. <?php
  97.  
  98. return ob_get_clean();
  99.  
  100. }
  101.  
  102. function podcasts_content($podcasts) {
  103.  
  104. $rows = $podcasts['rows'];
  105.  
  106. ob_start();
  107.  
  108. foreach ($rows as $row) {
  109.  
  110. ?>
  111. <div class="podcast-row">
  112.  
  113. <div class="podcast-left">
  114. <a href="<?php echo $row['category_url']; ?>"><img src="<?php echo $row['category_img']; ?>" /></a>
  115. </div>
  116.  
  117. <div class="podcast-right">
  118. <div class="podcast">
  119. <a href="<?php echo $row['podcast_url']; ?>" title="<?php echo esc_attr($row['title']); ?>">
  120. <img src="<?php echo $row['podcast_img']; ?>" />
  121. </a>
  122. <h5><a href="<?php echo $row['podcast_url']; ?>"><?php echo $row['title']; ?></a></h5>
  123.  
  124. </div>
  125. </div>
  126.  
  127. </div><?php
  128.  
  129. }
  130.  
  131. return ob_get_clean();
  132.  
  133. }
  134.  
  135. function print_issue_widget() {
  136.  
  137. $this->is_rendered = true;
  138.  
  139. ob_start();
  140.  
  141. ?>
  142.  
  143. <!-- <div id="print-issue-container"> -->
  144.  
  145. <!-- <div id="podcasts-loader-wrap"></div> -->
  146.  
  147. <div id="print-issue">
  148. <div class="inner">
  149. <h4><a href="<?php echo $this->jj_url; ?>print">Print</a></h4>
  150. <a id="print-issue-wrapper" href=""><img id="print-issue-img" src="" style="display:none;" /></a>
  151. </div>
  152. </div> <!-- print -->
  153.  
  154.  
  155. <!-- </div> -->
  156.  
  157. <?php
  158.  
  159. return ob_get_clean();
  160.  
  161. }
  162.  
  163. public function widget_styles() {
  164.  
  165. ?><style>
  166.  
  167. /* Podcasts */
  168. #podcasts {
  169. background-color: #dfdfd5;
  170. background-color: #C0C0C0;
  171. background-color: #cdcbbd;
  172. box-shadow: inset 0 0 6px -2px #000000;
  173. padding: 15px;
  174. margin-bottom: 35px;
  175. }
  176. #podcasts h4 {
  177. width: 100%;
  178. margin: 0 0 30px;
  179. padding-bottom: 0;
  180. }
  181. #podcasts h4 a {
  182. text-indent: 100%;
  183. white-space: nowrap;
  184. overflow: hidden;
  185. background: url('<?php echo $this->jj_url.'wp-content/themes/JJ'; ?>/images/headers/header-podcasts.png') no-repeat center center;
  186. width: 100%;
  187. margin: 0 0 10px;
  188. padding: 0;
  189. background-size: contain;
  190. min-height: 73px;
  191. display: block;
  192. }
  193.  
  194. #podcasts h3 .wrap:before {
  195. border-top: 1px dotted #8997a1;
  196. content: "";
  197. margin: 0 auto;
  198. /* this centers the line to the full width specified */
  199. position: absolute;
  200. /* positioning must be absolute here, and relative positioning must be applied to the parent */
  201. top: 50%;
  202. left: 0;
  203. right: 0;
  204. bottom: 0;
  205. width: 100%;
  206. z-index: -1;
  207. }
  208.  
  209. #podcast-wrapper {
  210.  
  211. min-height: 290px;
  212.  
  213. }
  214.  
  215. #podcasts #podcast-wrapper {
  216. /* display: flex;
  217. flex-direction: row-reverse;
  218. flex-wrap: wrap-reverse;
  219. justify-content: space-between;*/
  220. display: flex;
  221. flex-direction: column;
  222. justify-content: space-between;
  223. }
  224. #podcasts #podcast-wrapper .podcast-row {
  225. margin-bottom: 20px;
  226. display: inline-flex;
  227. flex-direction: row;
  228. justify-content: space-between;
  229. }
  230. #podcasts #podcast-wrapper .podcast-row:last-child {
  231. margin-bottom: 0;
  232. }
  233. #podcasts #podcast-wrapper .podcast-row .podcast-left {
  234. width: 33%;
  235. }
  236. #podcasts #podcast-wrapper .podcast-row .podcast-left a {
  237. display: block;
  238. }
  239. #podcasts #podcast-wrapper .podcast-row .podcast-right {
  240. width: 64%;
  241. }
  242. #podcasts #podcast-wrapper .podcast-row .podcast-right .podcast {
  243. display: flex;
  244. flex-direction: row;
  245. justify-content: space-between;
  246. height: 100%;
  247. }
  248. #podcasts #podcast-wrapper .podcast-row .podcast-right .podcast > a {
  249. display: block;
  250. width: 70%;
  251. margin-right: 8px;
  252. max-height: 135px;
  253. overflow: hidden;
  254. }
  255. #podcasts #podcast-wrapper .podcast-row .podcast-right .podcast h5 {
  256. width: 55%;
  257. margin: 0;
  258. font-size: 16px;
  259. display: inline-flex;
  260. align-self: center;
  261. }
  262.  
  263. #podcasts #podcast-wrapper a img {
  264. display: block;
  265. width: 100%;
  266. height: auto;
  267.  
  268. }
  269.  
  270. #podcasts #podcast-wrapper a:first-child img {
  271. display: block;
  272. width: 100%;
  273. height: auto;
  274. }
  275.  
  276. /* Print */
  277. #print-issue {
  278. background-color: #dfdfd5;
  279. background-color: #C0C0C0;
  280. background-color: #cdcbbd;
  281. box-shadow: inset 0 0 6px -2px #000000;
  282. padding: 15px;
  283. }
  284. #print-issue h4 {
  285. width: 100%;
  286. margin: 0 0 30px;
  287. padding-bottom: 0;
  288. }
  289. #print-issue h4 a {
  290. text-indent: 100%;
  291. white-space: nowrap;
  292. overflow: hidden;
  293. background: url('<?php echo $this->jj_url.'wp-content/themes/JJ'; ?>/images/headers/header-print.png') no-repeat center center;
  294. width: 100%;
  295. margin: 0 0 10px;
  296. padding: 0;
  297. background-size: contain;
  298. min-height: 71px;
  299. display: block;
  300. }
  301. #print-issue h3 {
  302. width: 100%;
  303. text-align: center;
  304. margin: 20px 0;
  305. font-size: 18px;
  306. color: #306b84;
  307. }
  308. #print-issue h3 .wrap {
  309. position: relative;
  310. z-index: 1;
  311. display: block;
  312. max-width: 60%;
  313. margin: 0 auto;
  314. }
  315. #print-issue h3 .wrap span {
  316. background-color: #dfdfd5;
  317. background-color: #C0C0C0;
  318. background-color: #cdcbbd;
  319. padding: 0 5px;
  320. }
  321. #print-issue h3 .wrap:before {
  322. border-top: 1px dotted #8997a1;
  323. content: "";
  324. margin: 0 auto;
  325. /* this centers the line to the full width specified */
  326. position: absolute;
  327. /* positioning must be absolute here, and relative positioning must be applied to the parent */
  328. top: 50%;
  329. left: 0;
  330. right: 0;
  331. bottom: 0;
  332. width: 100%;
  333. z-index: -1;
  334. }
  335. #print-issue img {
  336. width: 100%;
  337. height: auto;
  338. box-shadow: 3px 3px 5px #666;
  339. }
  340.  
  341. #print-issue-wrapper {
  342.  
  343. // min-height: 430px;
  344.  
  345. }
  346.  
  347. </style><?php
  348.  
  349. }
  350.  
  351. public function widget_scripts() {
  352.  
  353. //exit if the shortcode was not used on this page
  354. if (!$this->is_rendered)
  355. return;
  356.  
  357. ?><script>(function() {
  358.  
  359. //containers where the dynamic content is inserted
  360. var printIssueWrapper = document.getElementById('print-issue-wrapper'),
  361. podcastWrapper = document.getElementById('podcast-wrapper');
  362.  
  363. //if the widget1 is present, load its content
  364. if (printIssueWrapper || podcastWrapper)
  365. loadData();
  366.  
  367. //used to escape data from the remote server
  368. function escapeHTML(s) {
  369.  
  370. return s.replace(/&/g, "&amp;").replace(/</g, "&lt;").replace(/>/g, "&gt;").replace(/\//g, "&#x2F;");
  371.  
  372. }
  373.  
  374. function loadData() {
  375.  
  376. jQuery.ajax({
  377.  
  378. type: 'GET',
  379. url: <?php echo json_encode(admin_url( 'admin-ajax.php?action=get-jj-widgets-data' )); ?>,
  380. contentType: 'application/json',
  381. success: ajaxSuccess,
  382. error: ajaxError
  383.  
  384. });
  385.  
  386. }
  387.  
  388. function ajaxSuccess(data) {
  389.  
  390. if (data.error) {
  391.  
  392. console.log('Warning: error retrieving roundtable posts: ' + data.error);
  393. return;
  394.  
  395. }
  396.  
  397. if (printIssueWrapper)
  398. renderPrintIssue(data.print_issue);
  399.  
  400. if (podcastWrapper)
  401. renderPodcasts(data.podcasts_html);
  402.  
  403. }
  404.  
  405. function renderPodcasts(html) {
  406.  
  407. podcastWrapper.innerHTML = html;
  408.  
  409.  
  410. }
  411.  
  412. function renderPrintIssue(printIssue) {
  413.  
  414. printIssueWrapper.href = printIssue.issue_url;
  415.  
  416. document.getElementById('print-issue-img').src = printIssue.issue_img;
  417. document.getElementById('print-issue-img').style.display = '';
  418. return;
  419.  
  420. widget2Container.innerHTML = data.html;
  421.  
  422. widget2Container.style.opacity = 1;
  423.  
  424. var loaderWrap = document.getElementById('drw2-loader-wrap')
  425.  
  426. loaderWrap.style.opacity = 0;
  427.  
  428. loaderWrap.addEventListener('transitionend', function(e) {
  429.  
  430. loaderWrap.style.display = 'none';
  431.  
  432. });
  433.  
  434. }
  435.  
  436. function ajaxError(jqXHR) {
  437.  
  438. console.log('Warning: error retrieving roundtable posts');
  439.  
  440. }
  441.  
  442. }());
  443.  
  444.  
  445. </script><?php
  446.  
  447.  
  448. }
  449.  
  450.  
  451. //get the data from Jewish Journal to display the widgets here
  452. public function widgets_ajax() {
  453.  
  454. $response = array (
  455.  
  456. 'success' => false
  457.  
  458. );
  459.  
  460. header('Content-Type: application/json');
  461.  
  462. $api_url = $this->jj_url . 'wp-admin/admin-ajax.php?action=daily-roundtable-widgets-data';
  463.  
  464. $request = wp_remote_get( $api_url );
  465.  
  466. if( is_wp_error( $request ) ) {
  467.  
  468. $response['error'] = 'Unable to connect to remote server';
  469. echo json_encode( $response );
  470. wp_die();
  471.  
  472. }
  473.  
  474. $body = wp_remote_retrieve_body( $request );
  475.  
  476. $data = json_decode($body, true);
  477.  
  478. $response['success'] = true;
  479.  
  480. //build the html from the data and the template and output it
  481. $response['podcasts_html'] = $this->podcasts_content($data['podcasts']);
  482.  
  483. //output print issue data
  484. $response['print_issue'] = $data['print_issue'];
  485.  
  486. echo json_encode($response);
  487.  
  488. wp_die();
  489.  
  490. }
  491.  
  492.  
  493. //return the current roundtable on the homepage as json
  494. function widget1_data_for_jj() {
  495.  
  496. /* example output:
  497. {
  498. "success": true,
  499. "posts": [
  500.  
  501. { "title": "Post 1" },
  502. { "title": "Post 2" },
  503. { "title": "Post 3" },
  504. { "title": "Post 4" },
  505. { "title": "Post 5" },
  506. ]
  507.  
  508. }
  509.  
  510. */
  511.  
  512. $response = array (
  513.  
  514. 'success' => false
  515.  
  516. );
  517.  
  518. header('Content-Type: application/json');
  519.  
  520.  
  521. //get the id of the roundtable displayed on the homepage
  522. //I got this code partially from the JJ Daily theme, file: page-homepage.php
  523.  
  524. $parent_id = null;
  525.  
  526. $parent = new WP_Query( array(
  527.  
  528. 'post_type' => 'daily_roundtable',
  529. 'post_parent' => 0
  530.  
  531. ) );
  532.  
  533. while ( $parent->have_posts() ) {
  534.  
  535. $parent->the_post();
  536. $parent_id = get_the_ID();
  537.  
  538. }
  539.  
  540. if (!$parent_id) {
  541.  
  542. $response['error'] = 'Parent post not found';
  543. echo json_encode($response);
  544. wp_die();
  545.  
  546. }
  547.  
  548. //once we have the parent post id, we can fetch its children
  549. $roundtable_posts = new WP_Query( array(
  550.  
  551. 'post_type' => 'any',
  552. 'posts_per_page' => 3,
  553. //'posts_per_page' => -1,
  554. 'post_parent' => $parent_id,
  555. 'order' => 'ASC',
  556. 'orderby' => 'menu_order'
  557.  
  558. ) );
  559.  
  560. //check if we have any posts
  561. if (!$roundtable_posts->have_posts()) {
  562.  
  563. $response['error'] = 'No posts';
  564. echo json_encode($response);
  565. wp_die();
  566.  
  567. }
  568.  
  569. $response['posts'] = array();
  570.  
  571. //iterate the roundtable posts
  572. while ( $roundtable_posts->have_posts() ) {
  573.  
  574. $roundtable_posts->the_post();
  575. array_push($response['posts'], array ( 'title' => html_entity_decode(get_the_title()) ));
  576.  
  577. }
  578.  
  579. wp_reset_postdata();
  580.  
  581. $response['success'] = true;
  582. echo json_encode($response);
  583. wp_die();
  584.  
  585. }
  586.  
  587.  
  588. function widget2_data_for_jj() {
  589.  
  590. $response = array (
  591.  
  592. 'success' => false
  593.  
  594. );
  595.  
  596. header('Content-Type: application/json');
  597.  
  598.  
  599. //get the id of the roundtable displayed on the homepage
  600. //I got this code partially from the JJ Daily theme, file: page-homepage.php
  601.  
  602. $parent_id = null;
  603.  
  604. $parent = new WP_Query( array(
  605.  
  606. 'post_type' => 'daily_roundtable',
  607. 'post_parent' => 0
  608.  
  609. ) );
  610.  
  611. while ( $parent->have_posts() ) {
  612.  
  613. $parent->the_post();
  614. $parent_id = get_the_ID();
  615.  
  616. }
  617.  
  618. if (!$parent_id) {
  619.  
  620. $response['error'] = 'Parent post not found';
  621. echo json_encode($response);
  622. wp_die();
  623.  
  624. }
  625.  
  626. //once we have the parent post id, we can fetch its children
  627. $roundtable_posts = new WP_Query( array(
  628.  
  629. 'post_type' => 'any',
  630. 'posts_per_page' => -1,
  631. 'post_parent' => $parent_id,
  632. 'order' => 'ASC',
  633. 'orderby' => 'menu_order',
  634. 'posts_per_page' => 3
  635.  
  636. ) );
  637.  
  638. //check if we have any posts
  639. if (!$roundtable_posts->have_posts()) {
  640.  
  641. $response['error'] = 'No posts';
  642. echo json_encode($response);
  643. wp_die();
  644.  
  645. }
  646.  
  647. $roundtable = array();
  648.  
  649. //iterate the roundtable posts
  650. while ( $roundtable_posts->have_posts() ) {
  651.  
  652. $roundtable_posts->the_post();
  653.  
  654. $stories = array();
  655.  
  656. //iterate the custom article field "sub-stories"
  657. while (have_rows('article')) {
  658.  
  659. the_row();
  660.  
  661. array_push($stories, array(
  662. 'title' => get_sub_field('title'),
  663. 'link' => get_sub_field('link'),
  664. 'source' => get_sub_field('source'),
  665. 'image' => get_sub_field('image'),
  666. 'summary' => get_sub_field('summary'),
  667. 'by_line' => get_sub_field('by_line'),
  668. 'quote' => get_sub_field('quote'),
  669.  
  670. ));
  671.  
  672. }
  673.  
  674. array_push($roundtable, array (
  675.  
  676. 'title' => html_entity_decode(get_the_title()),
  677. 'take' => get_field('our_take'),
  678. 'id' => get_the_ID(),
  679. 'stories' => $stories
  680.  
  681. ));
  682.  
  683. }
  684.  
  685. wp_reset_postdata();
  686.  
  687. $response['success'] = true;
  688. $response['roundtable'] = $roundtable;
  689. echo json_encode($response);
  690. wp_die();
  691.  
  692. }
  693.  
  694.  
  695. }
  696.  
  697. $Jewish_Journal_Connector = new Jewish_Journal_Connector();
  698.  
  699.  
  700. ?>
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement