Title: ESI API Help &lt;3
Last modified: April 25, 2018

---

# ESI API Help <3

 *  Resolved [conorseed](https://wordpress.org/support/users/conorseed/)
 * (@conorseed)
 * [8 years, 1 month ago](https://wordpress.org/support/topic/esi-api-help-3/)
 * Hey team, I trust you’re having a great day!
 * I’ve seen your [ESI examples here](https://www.litespeedtech.com/support/wiki/doku.php/litespeed_wiki:cache:lscwp:esi_sample)
   but can’t quite wrap my head around how to do it
 * It grabs a value from the database using get_option() and spits it out as a json
   variable to be used client side. If the value is more than an hour old, it updates
   the value through a series of API requests and update_option(). The shortcode
   also takes attributes in order for the output to be filtered on client side.
 * Basically, it’s the “Upcoming Courses” section on the home page, and a number
   of other pages, but it will display differently depending on the shortcode attributes.
 * Any advice? Would it be helpful to view the code? Thanks for your time.
 * The page I need help with: _[[log in](https://login.wordpress.org/?redirect_to=https%3A%2F%2Fwordpress.org%2Fsupport%2Ftopic%2Fesi-api-help-3%2F%3Foutput_format%3Dmd&locale=en_US)
   to see the link]_

Viewing 15 replies - 1 through 15 (of 19 total)

1 [2](https://wordpress.org/support/topic/esi-api-help-3/page/2/?output_format=md)
[→](https://wordpress.org/support/topic/esi-api-help-3/page/2/?output_format=md)

 *  Plugin Support [Hai Zheng⚡](https://wordpress.org/support/users/hailite/)
 * (@hailite)
 * [8 years, 1 month ago](https://wordpress.org/support/topic/esi-api-help-3/#post-10218950)
 * Can you give the PHP snippet where you generated that json data?
 *  Thread Starter [conorseed](https://wordpress.org/support/users/conorseed/)
 * (@conorseed)
 * [8 years, 1 month ago](https://wordpress.org/support/topic/esi-api-help-3/#post-10218994)
 * Sure thing 🙂 This is the quick and dirty version of it at the moment:
 *     ```
       /* API CALL */
       function cd_acuity_getCoursesv2( $course = '', $id = FALSE ){
   
           // Vars
           $userID = 'XXXXXXX';
           $key = 'XXXXXXXX';
           $date = new DateTime(); $fdate = new DateTime();
           $fdate = ($course !== 'DDC') ? $fdate->modify('+4 month') : $fdate->modify('+6 month');
   
           // URL
           if( $id ){
               $url = 'https://acuityscheduling.com/api/v1/availability/classes?appointmentTypeID='.$id;
           } else{
               $url = 'https://acuityscheduling.com/api/v1/availability/classes?minDate='.$date->format('Y-m-d').'&maxDate='.$fdate->format('Y-m-d'); //includeUnavailable=true&
           }
   
           // Initiate curl:
           // GET request, so no need to worry about setting post vars:
           $ch = curl_init();
           curl_setopt($ch, CURLOPT_URL, $url);
   
           // Grab response as string:
           curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
   
           // HTTP auth:
           curl_setopt($ch, CURLOPT_USERPWD, "$userID:$key");
   
           // Execute request:
           $result = curl_exec($ch); 
   
           // Don't forget to close the connection!
           curl_close($ch);
   
           // Catch Error or Return JSON
           return json_decode($result, true);
       }
   
       /* SHORTCODE */
       function cd_acuityShortcodev2($atts){
   
           // Set Atts
           $atts = shortcode_atts(
               array(
                   'course' => '',
               ),
               $atts
           );
   
           $current_time = current_time('timestamp');
   
           // Get Saved Option
           $resultArr = json_decode( get_option('2ds_courses'), true );
   
           // If Saved json older than 1 hour, get updated courses
           if( $current_time - $resultArr['updated'] > 3599 ){
               // Vars
               $resultArr = array( 
                   'data'      => [],
                   'updated'   => ''
               );
               $ddcArr = [];
   
               // Get RF Courses
               $rfcourses = cd_acuity_getCoursesv2();
   
               // Error Check
               if (isset($rfcourses['error'])){
                   return 'Uh oh. Something Went Wrong.';
               }
   
               // Output RF Courses
               foreach ($rfcourses as $rf){
   
                   // Filter out DDC
                   if ( strpos( $rf['name'], 'DDC' ) === FALSE ){
   
                       // Get Vars
                       $rfcourse = [];
                       $rfcourse['name'] = $rf['name'];
                       $rfcourse['date'] = cd_acuityGetDate($rf['time']);
                       $rfcourse['id'] = $rf['appointmentTypeID'];
                       $rfcourse['slots'] = $rf['slotsAvailable']; 
   
                       // Push to final array
                       array_push($resultArr['data'], $rfcourse);
                   }
               }
   
               // Get DDC Courses
               $ddccourses = cd_acuity_getCoursesv2('DDC');
   
               // Error Check
               if (isset($ddccourses['error'])){
                   return 'Uh oh. Something Went Wrong.';
               }
   
               // Output DDC Courses
               foreach ($ddccourses as $ddc){
                   if ( strpos( $ddc['name'], 'DDC' ) !== FALSE ){
   
                       // Get Vars
                       $ddccourse = [];
                       $ddccourse['name'] = $ddc['name'];
                       $ddccourse['id'] = $ddc['appointmentTypeID'];
                       $ddccourse['slots'] = $ddc['slotsAvailable']; 
   
                       // Test
                       foreach ($ddcArr as $test){
                           if ($test === $ddccourse['id']){ continue 2;}
                       }
   
                       // Get Dates
                       $ddcdates = cd_acuity_getCoursesv2('', $ddccourse['id']);
                       $ddccourse['date'] = cd_acuityGetDate($ddcdates[0]['time']);
                       $ddccourse['date2'] = cd_acuityGetDate($ddcdates[1]['time']);
                       $ddccourse['date3'] = cd_acuityGetDate($ddcdates[2]['time']);
                       $ddccourse['date4'] = cd_acuityGetDate($ddcdates[3]['time']);
   
                       // Push to final array
                       array_push($resultArr['data'], $ddccourse);
   
                       // Push ID to ddcArr for testing
                       array_push($ddcArr, $ddccourse['id']);
                   }
               }
   
               // Sort Final Array
               usort($resultArr['data'], function($a, $b){
                   $t1 = strtotime($a['date']);
                   $t2 = strtotime($b['date']);
                   return $t1 - $t2;
               });
   
               // Add DateTime to Array
               $resultArr['updated'] = $current_time;
           } 
   
           // Change Final Array to JSON
           $json = json_encode($resultArr);
   
           // Update JSON in Database
           if( $current_time - $resultArr['updated'] > 3599 ){
               update_option( '2ds_courses', $json );
               error_log('UPDATED');
           }
   
   
           // Output
           $result = '<div class="acuity-courses-wrapper owl-carousel owl-theme"></div>';
           $result.= '<script type="text/javascript">var acuityCoursesArr = ' . $json . ';';
           $result.= 'var acuityCoursesFilter = "'.$atts['course'].'";';
           $result.= <<<EOT
           jQuery(function(a){acuityCoursesArr.data.length>0?(a.each(acuityCoursesArr.data,function(e,s){var t=s.name,p=~t.indexOf("DDC")?s.date+", "+s.date2+", "+s.date3+", "+s.date4:s.date,r=s.id,n=s.slots;acuityCoursesFilter?~t.indexOf(acuityCoursesFilter)&&a(".acuity-courses-wrapper").append('<div class="course" type="'+t+'"><span class="acuity-name">'+t+'</span><span class="acuity-date">'+p+'</span><a target="_blank" href="https://2drivesafe.as.me/?appointmentType='+r+'">Book Now<span>'+n+" Spots Left</span></a></div>"):a(".acuity-courses-wrapper").append('<div class="course" type="'+t+'"><span class="acuity-name">'+t+'</span><span class="acuity-date">'+p+'</span><a target="_blank" href="https://2drivesafe.as.me/?appointmentType='+r+'">Book Now<span>'+n+" Seats Left</span></a></div>")}),a(".acuity-courses-wrapper").owlCarousel({loop:!0,margin:10,nav:!0,navText:["< Prev","Next >"],responsive:{0:{items:1},600:{items:2},1e3:{items:3}}})):(a(".acuity-courses-wrapper").append("No courses found."),a(".acuity-courses-wrapper").owlCarousel())});
       EOT;
   
           $result.= '</script>';
   
           return $result;
       }
       add_shortcode('acuitycourses', 'cd_acuityShortcodev2');
   
       function cd_acuityGetDate($time){
           $date = new DateTime($time);
           return $date->format('D j M, g:ia');
       }
       ```
   
 *  Plugin Support [Hai Zheng⚡](https://wordpress.org/support/users/hailite/)
 * (@hailite)
 * [8 years, 1 month ago](https://wordpress.org/support/topic/esi-api-help-3/#post-10219032)
 * Just create a new “middleware” function.
 * e.g.
 *     ```
       add_shortcode('acuitycourses', 'esi_block') ;
       function esi_block( $params ) {
           return LiteSpeed_Cache_API::esi_url( 'my_plugin_esi', 'My Plugin Name', $params ) ;
       }
   
       LiteSpeed_Cache_API::hook_tpl_esi('my_plugin_esi', 'hook_esi' ) ;
       function hook_esi( $params ) {
           echo cd_acuityShortcodev2( $params ) ;
           exit ;
       }
       ```
   
    -  This reply was modified 8 years, 1 month ago by [Hai Zheng⚡](https://wordpress.org/support/users/hailite/).
 *  Thread Starter [conorseed](https://wordpress.org/support/users/conorseed/)
 * (@conorseed)
 * [8 years, 1 month ago](https://wordpress.org/support/topic/esi-api-help-3/#post-10219041)
 * Brilliant idea.
 * I assume that the $params would be the shortcode $atts? I don’t need to include
   any other parameters in there?
 *  Plugin Support [Hai Zheng⚡](https://wordpress.org/support/users/hailite/)
 * (@hailite)
 * [8 years, 1 month ago](https://wordpress.org/support/topic/esi-api-help-3/#post-10219068)
 * You can pass any parameters into ESI API. It will give them back to you anyways.
   You can even encode in your way first before give to ESI, just don’t forget to
   decode it when use it.
 *  Thread Starter [conorseed](https://wordpress.org/support/users/conorseed/)
 * (@conorseed)
 * [8 years, 1 month ago](https://wordpress.org/support/topic/esi-api-help-3/#post-10219072)
 * Ok thanks! I’ll give it a go and come back if I have any issues 🙂
 *  Thread Starter [conorseed](https://wordpress.org/support/users/conorseed/)
 * (@conorseed)
 * [8 years, 1 month ago](https://wordpress.org/support/topic/esi-api-help-3/#post-10219126)
 * Hey, I get the below error. How do I include the api in my plugin? 🙂
 * `Uncaught Error: Class 'LiteSpeed_Cache_API' not found in path/to/my/plugin`
 *  Plugin Support [Hai Zheng⚡](https://wordpress.org/support/users/hailite/)
 * (@hailite)
 * [8 years, 1 month ago](https://wordpress.org/support/topic/esi-api-help-3/#post-10219152)
 * You should call them after `after_setup_theme`.
 *  Thread Starter [conorseed](https://wordpress.org/support/users/conorseed/)
 * (@conorseed)
 * [8 years, 1 month ago](https://wordpress.org/support/topic/esi-api-help-3/#post-10219159)
 * Sorry [@hailite](https://wordpress.org/support/users/hailite/), I don’t quite
   understand. Can you expand on that please?
 *  Plugin Support [Hai Zheng⚡](https://wordpress.org/support/users/hailite/)
 * (@hailite)
 * [8 years, 1 month ago](https://wordpress.org/support/topic/esi-api-help-3/#post-10220655)
 * It is a hook. When you get that error that means you try to use our class before
   its included by WP. If your plugin loads earlier than LSCWP, and you directly
   used LiteSpeed_Cache_API, it will happen.
 * I don’t think you should run LiteSpeed_Cache_API when your plugin is included
   by WP in wp-settings.php line 301 `// Load active plugins.`
 *  Thread Starter [conorseed](https://wordpress.org/support/users/conorseed/)
 * (@conorseed)
 * [8 years, 1 month ago](https://wordpress.org/support/topic/esi-api-help-3/#post-10223087)
 * That makes sense now thank you! 🙂 I got it working by using the `after_setup_theme’
   action as you suggested.
 * I do have another question though: does an ESI block load fresh every time, even
   for logged out users?
 *  Thread Starter [conorseed](https://wordpress.org/support/users/conorseed/)
 * (@conorseed)
 * [8 years, 1 month ago](https://wordpress.org/support/topic/esi-api-help-3/#post-10224158)
 * Ok, so I found in the documentation to set the below but it’s still caching the
   block in the public cache. Any ideas?
 * `LiteSpeed_Cache_API::esi_url($block_id, $wrapper, $params = array(), $control
   = 'private,no-vary')`
 * _Set `$control = 'no-cache'` to set the ESI block as non-cacheable._
 *  Plugin Support [Hai Zheng⚡](https://wordpress.org/support/users/hailite/)
 * (@hailite)
 * [8 years, 1 month ago](https://wordpress.org/support/topic/esi-api-help-3/#post-10226118)
 * Do you want it to be no cache? if its no cache, it will hit php each time even
   the main page is cached, that will slow down the main page loading. That will
   make the cache of main page is not that useful.
 * Private cache has a separate cache TTL, default to 1800s in General setting. 
   If you want to short that particular ESI TTL, just use API to set TTL in hook_esi()
   before echo.
 *  Thread Starter [conorseed](https://wordpress.org/support/users/conorseed/)
 * (@conorseed)
 * [8 years, 1 month ago](https://wordpress.org/support/topic/esi-api-help-3/#post-10230717)
 * [@hailite](https://wordpress.org/support/users/hailite/) Thanks for the response.
 * I thought no cache would be the best option in terms of making sure the block
   always shows the most recent information. It is linked into a booking system 
   via API: it shows upcoming courses, as well as how many spots are left on each
   course.
 * Currently (even with the esi block set to “no-cache”), the whole page is cached.
   Which means it’s outdated after an hour – often showing the wrong number of spots
   left, or a course which is no longer available to book.
 * If I set it to “private”, will the block always show the most recent info for
   ANY user (logged in or not)?
    -  This reply was modified 8 years, 1 month ago by [conorseed](https://wordpress.org/support/users/conorseed/).
 *  Plugin Support [LiteSpeed Lisa](https://wordpress.org/support/users/lclarke/)
 * (@lclarke)
 * [8 years, 1 month ago](https://wordpress.org/support/topic/esi-api-help-3/#post-10232007)
 * Hi, [@conorseed](https://wordpress.org/support/users/conorseed/)
 * > If I set it to “private”, will the block always show the most recent info for
   > ANY user (logged in or not)?
 * Not exactly. Here’s what the different ESI block settings mean:
    - Public: there is one copy of the ESI block stored in cache, and that same 
      copy is served to anyone who requests it.
    - Private: there is a separate copy of the ESI block stored in the cache for
      each person who requests it. So, for example, if there are 300 visitors to
      your site, there are 300 individual copies of the ESI block cached.
    - No Cache: the block is not cached at all, and PHP must run each time the ESI
      block is requested.
 * As to which one you should use? It’s tempting to choose “No Cache” when you want
   up-to-the-minute information, but this can slow down your site considerably. 
   The biggest benefit to caching is that PHP does not have to be invoked when a
   page is served. If you have uncached blocks on your page, you lose that benefit.
 * Rather than setting your ESI block to “no Cache” it is better to make it either
   Public or Private, and then set a very small TTL, say 10 minutes. Then, the data
   will never be more than 10 minutes old, and any visitors in that time period 
   will get the speed benefits of having the entire page served from cache. If you
   can go longer than 10 minutes, all the better.
 * Now, as far as whether it should be Public or Private? That depends on the content
   of the block. Does everyone who visits the page see the same content in that 
   block? If so, then it can be Public. Is the block somehow personalized for individual
   users? Then it should be Private.
 * I hope that clears it up! If you’d like more information on this topic, along
   with some examples, take a look at our blog. We’ve got a few different posts 
   that explain the concepts involved in Private/Public/ESI caching, but [this one](https://blog.litespeedtech.com/2017/09/06/wpw-esi-and-litespeed-cache/)
   is probably the most relevant to your situation.
 * Let us know if you have any more questions!

Viewing 15 replies - 1 through 15 (of 19 total)

1 [2](https://wordpress.org/support/topic/esi-api-help-3/page/2/?output_format=md)
[→](https://wordpress.org/support/topic/esi-api-help-3/page/2/?output_format=md)

The topic ‘ESI API Help <3’ is closed to new replies.

 * ![](https://ps.w.org/litespeed-cache/assets/icon-256x256.png?rev=2554181)
 * [LiteSpeed Cache](https://wordpress.org/plugins/litespeed-cache/)
 * [Frequently Asked Questions](https://wordpress.org/plugins/litespeed-cache/#faq)
 * [Support Threads](https://wordpress.org/support/plugin/litespeed-cache/)
 * [Active Topics](https://wordpress.org/support/plugin/litespeed-cache/active/)
 * [Unresolved Topics](https://wordpress.org/support/plugin/litespeed-cache/unresolved/)
 * [Reviews](https://wordpress.org/support/plugin/litespeed-cache/reviews/)

 * 19 replies
 * 3 participants
 * Last reply from: [LiteSpeed Lisa](https://wordpress.org/support/users/lclarke/)
 * Last activity: [8 years, 1 month ago](https://wordpress.org/support/topic/esi-api-help-3/page/2/#post-10239030)
 * Status: resolved