Google_Places_Reviews

Google Places Reviews.

Defined (1)

The class is defined in the following location(s).

/classes/widget.php  
  1. class Google_Places_Reviews extends WP_Widget { 
  2.  
  3. /** 
  4. * Plugin Options from Options Panel 
  5. * @var mixed|void 
  6. */ 
  7. public $options; 
  8.  
  9. /** 
  10. * Google API key 
  11. * @var string 
  12. */ 
  13. public $api_key; 
  14.  
  15.  
  16. /** 
  17. * Array of Private Options 
  18. * @since 1.0.0 
  19. * @var array 
  20. */ 
  21. public $widget_fields = array( 
  22. 'title' => '',  
  23. 'location' => '',  
  24. 'reference' => '',  
  25. 'place_id' => '',  
  26. 'place_type' => '',  
  27. 'cache' => '',  
  28. 'disable_title_output' => '',  
  29. 'widget_style' => 'Minimal Light',  
  30. 'review_filter' => '',  
  31. 'review_limit' => '5',  
  32. 'review_characters' => '1',  
  33. 'hide_header' => '',  
  34. 'hide_out_of_rating' => '',  
  35. 'hide_google_image' => '',  
  36. 'target_blank' => '1',  
  37. 'no_follow' => '1',  
  38. ); 
  39.  
  40.  
  41. /** 
  42. * Register widget with WordPress. 
  43. */ 
  44. public function __construct() { 
  45.  
  46. parent::__construct( 
  47. 'gpr_widget', // Base ID 
  48. 'Google Places Reviews', // Name 
  49. array( 
  50. 'classname' => 'google-places-reviews',  
  51. 'description' => __( 'Display user reviews for any location found on Google Places.', 'google-places-reviews' ) 
  52. ); 
  53.  
  54. $this->options = get_option( 'googleplacesreviews_options' ); 
  55. //API key (muy importante!) 
  56. $this->api_key = $this->options['google_places_api_key']; 
  57.  
  58. //Hooks 
  59. add_action( 'wp_enqueue_scripts', array( $this, 'frontend_widget_scripts' ) ); 
  60. add_action( 'admin_enqueue_scripts', array( $this, 'admin_widget_scripts' ) ); 
  61. add_action( 'wp_ajax_gpr_free_clear_widget_cache', array( $this, 'clear_widget_cache' ) ); 
  62.  
  63.  
  64. /** 
  65. * Admin Widget Scripts 
  66. * @description: Load Widget JS Script ONLY on Widget page 
  67. * @param $hook 
  68. */ 
  69. function admin_widget_scripts( $hook ) { 
  70.  
  71. $suffix = defined( 'SCRIPT_DEBUG' ) && SCRIPT_DEBUG ? '' : '.min'; 
  72. $apikey = $this->options['google_places_api_key']; 
  73.  
  74. if ( $hook == 'widgets.php' || ( $hook == 'customize.php' && defined( 'SITEORIGIN_PANELS_VERSION' ) ) ) { 
  75.  
  76. wp_register_script( 'gpr_google_places_gmaps', 'https://maps.googleapis.com/maps/api/js?v=3.exp&libraries=places&key=' . $apikey, array( 'jquery' ) ); 
  77. wp_enqueue_script( 'gpr_google_places_gmaps' ); 
  78.  
  79. wp_register_script( 'gpr_widget_admin_tipsy', plugins_url( 'assets/js/gpr-tipsy' . $suffix . '.js', dirname( __FILE__ ) ), array( 'jquery' ) ); 
  80. wp_enqueue_script( 'gpr_widget_admin_tipsy' ); 
  81.  
  82. wp_register_script( 'gpr_widget_admin_scripts', plugins_url( 'assets/js/admin-widget' . $suffix . '.js', dirname( __FILE__ ) ), array( 'jquery' ) ); 
  83. wp_enqueue_script( 'gpr_widget_admin_scripts' ); 
  84.  
  85. wp_localize_script( 'gpr_widget_admin_scripts', 'gpr_ajax_object', array( 
  86. 'ajax_url' => admin_url( 'admin-ajax.php' ),  
  87. 'i18n' => array( 
  88. 'google_auth_error' => sprintf( __( '%1$sGoogle API Error:%2$s Due to recent changes by Google you must now add the Maps API to your existing API key in order to use the Location Lookup feature of the Google Places Widget. %3$sView documentation here%4$s', 'google-maps-pro' ), '<strong>', '</strong>', '<br><a href="https://wordimpress.com/documentation/google-places-reviews/creating-your-google-places-api-key/" target="_blank" class="new-window">', '</a>' ) ) 
  89. ) ); 
  90.  
  91. wp_register_style( 'gpr_widget_admin_tipsy', plugins_url( 'assets/css/gpr-tipsy' . $suffix . '.css', dirname( __FILE__ ) ) ); 
  92. wp_enqueue_style( 'gpr_widget_admin_tipsy' ); 
  93.  
  94.  
  95. wp_register_style( 'gpr_widget_admin_css', plugins_url( 'assets/css/admin-widget' . $suffix . '.css', dirname( __FILE__ ) ) ); 
  96. wp_enqueue_style( 'gpr_widget_admin_css' ); 
  97.  
  98.  
  99.  
  100.  
  101.  
  102. /** 
  103. * Frontend Scripts 
  104. * @description: Adds Google Places Reviews Stylesheets 
  105. */ 
  106. function frontend_widget_scripts() { 
  107.  
  108. $suffix = defined( 'SCRIPT_DEBUG' ) && SCRIPT_DEBUG ? '' : '.min'; 
  109. $gpr_css = plugins_url( 'assets/css/google-places-reviews' . $suffix . '.css', dirname( __FILE__ ) ); 
  110. wp_register_style( 'gpr_widget', $gpr_css ); 
  111.  
  112.  
  113. /** 
  114. * Front-end display of widget. 
  115. * @see WP_Widget::widget() 
  116. * @param array $args 
  117. * @param array $instance 
  118. * @return bool 
  119. */ 
  120. function widget( $args, $instance ) { 
  121.  
  122. if ( $this->options['disable_css'] !== 'on' ) { 
  123. wp_enqueue_style( 'gpr_widget' ); 
  124.  
  125. //@TODO: Remove usage 
  126. extract( $args ); 
  127.  
  128. //loop through options array and save variables for usage within function 
  129. foreach ( $instance as $variable => $value ) { 
  130. ${$variable} = ! isset( $instance[ $variable ] ) ? $this->widget_fields[ $variable ] : esc_attr( $instance[ $variable ] ); 
  131.  
  132. //Enqueue individual CSS if debug is on; otherwise plugin uses min version 
  133. if ( defined( 'SCRIPT_DEBUG' ) === true ) { 
  134. $this->enqueue_widget_theme_scripts( $widget_style ); 
  135.  
  136. //Check for a reference. If none, output error 
  137. if ( $reference === 'No location set' && empty( $place_id ) || empty( $reference ) && $place_id === 'No location set' ) { 
  138. $this->output_error_message( __( 'There is no location set for this widget yet.', 'google-places-reviews' ), 'error' ); 
  139.  
  140. return false; 
  141.  
  142.  
  143. //Title filter 
  144. if ( isset( $title ) ) { 
  145. $title = apply_filters( 'widget_title', $instance['title'] ); 
  146.  
  147.  
  148. // Open link in new window if set 
  149. if ( $target_blank == '1' ) { 
  150. $target_blank = 'target="_blank" '; 
  151. } else { 
  152. $target_blank = ''; 
  153.  
  154. // Add nofollow relation if set 
  155. if ( $no_follow == '1' ) { 
  156. $no_follow = 'rel="nofollow" '; 
  157. } else { 
  158. $no_follow = ''; 
  159.  
  160. /** 
  161. * Use the new Google Places ID (rather than reference) - but don't break older widgets/shortcodes 
  162. */ 
  163. if ( ( empty( $reference ) || $reference === 'No Location Set' && ! empty( $place_id ) && $place_id !== 'No location set' ) || strlen( $place_id ) < 80 ) { 
  164. $google_places_url = add_query_arg( 
  165. array( 
  166. 'placeid' => $place_id,  
  167. 'key' => $this->api_key 
  168. ),  
  169. 'https://maps.googleapis.com/maps/api/place/details/json' 
  170. ); 
  171. } else { 
  172. //User is on old Google's reference ID 
  173. $google_places_url = add_query_arg( 
  174. array( 
  175. 'reference' => $reference,  
  176. 'key' => $this->api_key 
  177. ),  
  178. 'https://maps.googleapis.com/maps/api/place/details/json' 
  179. ); 
  180. //serialize($instance) sets the transient cache from the $instance variable which can easily bust the cache once options are changed 
  181. $transient_unique_id = substr( $place_id, 0, 25 ); 
  182. $response = get_transient( 'gpr_widget_api_' . $transient_unique_id ); 
  183. $widget_options = get_transient( 'gpr_widget_options_' . $transient_unique_id ); 
  184. $serialized_instance = serialize( $instance ); 
  185. $cache = strtolower( $cache ); 
  186.  
  187. // Cache: cache option is enabled 
  188. if ( $cache !== 'none' ) { 
  189.  
  190. // Check for an existing copy of our cached/transient data 
  191. // also check to see if widget options have updated; this will bust the cache 
  192. if ( $response === false || $serialized_instance !== $widget_options ) { 
  193.  
  194. // It wasn't there, so regenerate the data and save the transient 
  195. //Get Time to Cache Data 
  196. $expiration = $cache; 
  197.  
  198. //Assign Time to appropriate Math 
  199. switch ( $expiration ) { 
  200. case '1 hour': 
  201. $expiration = 3600; 
  202. break; 
  203. case '3 hours': 
  204. $expiration = 3600 * 3; 
  205. break; 
  206. case '6 hours': 
  207. $expiration = 3600 * 6; 
  208. break; 
  209. case '12 hours': 
  210. $expiration = 60 * 60 * 12; 
  211. break; 
  212. case '1 day': 
  213. $expiration = 60 * 60 * 24; 
  214. break; 
  215. case '2 days': 
  216. $expiration = 60 * 60 * 48; 
  217. break; 
  218. case '1 week': 
  219. $expiration = 60 * 60 * 168; 
  220. break; 
  221.  
  222. // Cache data wasn't there, so regenerate the data and save the transient 
  223. $response = $this->get_reviews( $google_places_url ); 
  224. set_transient( 'gpr_widget_api_' . $transient_unique_id, $response, $expiration ); 
  225. set_transient( 'gpr_widget_options_' . $transient_unique_id, $serialized_instance, $expiration ); 
  226.  
  227. } //end response 
  228.  
  229.  
  230. } else { 
  231.  
  232. //No Cache option enabled; 
  233. $response = $this->get_reviews( $google_places_url ); 
  234.  
  235.  
  236. //Error message 
  237. if ( ! empty( $response->error_message ) ) { 
  238.  
  239. $this->output_error_message( $response->error_message, 'error' ); 
  240. $this->delete_transient_cache( $transient_unique_id ); 
  241.  
  242. return false; 
  243.  
  244. } //No Place ID or Reference set for this widget 
  245. elseif ( empty( $reference ) && empty( $place_id ) ) { 
  246.  
  247. $this->output_error_message( __( '<strong>INVALID REQUEST</strong>: Please check that this widget has a Google Place ID set.', 'google-places-reviews' ), 'error' ); 
  248. $this->delete_transient_cache( $transient_unique_id ); 
  249.  
  250. return false; 
  251.  
  252. } elseif ( isset( $response['error_message'] ) && ! empty( $response['error_message'] ) ) { 
  253.  
  254. $error = '<strong>' . $response['status'] . '</strong>: ' . $response['error_message']; 
  255. $this->output_error_message( $error, 'error' ); 
  256. $this->delete_transient_cache( $transient_unique_id ); 
  257.  
  258. return false; 
  259.  
  260.  
  261.  
  262. //Widget Style 
  263. $style = "gpr-" . sanitize_title( $widget_style ) . "-style"; 
  264. // no 'class' attribute - add one with the value of width 
  265. //@see http://wordpress.stackexchange.com/questions/18942/add-class-to-before-widget-from-within-a-custom-widget 
  266. if ( ! empty( $before_widget ) && strpos( $before_widget, 'class' ) === false ) { 
  267. $before_widget = str_replace( '>', 'class="' . $style . '"', $before_widget ); 
  268. } // there is 'class' attribute - append width value to it 
  269. elseif ( ! empty( $before_widget ) && strpos( $before_widget, 'class' ) !== false ) { 
  270. $before_widget = str_replace( 'class="', 'class="' . $style . ' ', $before_widget ); 
  271. } //no 'before_widget' at all so wrap widget with div 
  272. else { 
  273. $before_widget = '<div class="google-places-reviews">'; 
  274. $before_widget = str_replace( 'class="', 'class="' . $style . ' ', $before_widget ); 
  275.  
  276. /** Before widget */ 
  277. echo $before_widget; 
  278.  
  279. // if the title is set & the user hasn't disabled title output 
  280. if ( ! empty( $title ) && isset( $disable_title_output ) && $disable_title_output !== '1' ) { 
  281. /** Add class to before_widget from within a custom widget 
  282. http://wordpress.stackexchange.com/questions/18942/add-class-to-before-widget-from-within-a-custom-widget 
  283. */ 
  284. // no 'class' attribute - add one with the value of width 
  285. if ( ! empty( $before_title ) && strpos( $before_title, 'class' ) === false ) { 
  286. $before_title = str_replace( '>', ' class="gpr-widget-title">', $before_title ); 
  287. } //widget title has 'class' attribute 
  288. elseif ( ! empty( $before_title ) && strpos( $before_title, 'class' ) !== false ) { 
  289. $before_title = str_replace( 'class="', 'class="gpr-widget-title ', $before_title ); 
  290. } //no 'title' at all so wrap widget with div 
  291. else { 
  292. $before_title = '<h3 class="">'; 
  293. $before_title = str_replace( 'class="', 'class="gpr-widget-title ', $before_title ); 
  294. $after_title = empty( $after_title ) ? '</h3>' : $after_title; 
  295.  
  296. echo $before_title . $title . $after_title; 
  297.  
  298.  
  299. include( GPR_PLUGIN_PATH . '/inc/widget-frontend.php' ); 
  300.  
  301.  
  302.  
  303.  
  304. /** 
  305. * Update Widget 
  306. * @description: Saves the widget options 
  307. */ 
  308. function update( $new_instance, $old_instance ) { 
  309. $instance = $old_instance; 
  310. //loop through options array and save to new instance 
  311. foreach ( $this->widget_fields as $field => $value ) { 
  312. $instance[ $field ] = strip_tags( stripslashes( $new_instance[ $field ] ) ); 
  313.  
  314.  
  315. return $instance; 
  316.  
  317.  
  318. /** 
  319. * Widget Form 
  320. * @description: Responsible for outputting the backend widget form. 
  321. * @see WP_Widget::form() 
  322. */ 
  323. function form( $instance ) { 
  324.  
  325. //API Key Check: 
  326. if ( ! isset( $this->options['google_places_api_key'] ) || empty( $this->options['google_places_api_key'] ) ) { 
  327. $api_key_error = sprintf( __( '<p><strong>Notice: </strong>No Google Places API key detected. You will need to create an API key to use Google Places Reviews. API keys are manage through the <a href="%1$s" class="new-window" target="_blank">Google API Console</a>. For more information please see <a href="%2$s" target="_blank" class="new-window" title="Google Places API Introduction">this article</a>.</p> <p>Once you have obtained your API key enter it in the <a href="%3$s" title="Google Places Reviews Plugin Settings">plugin settings page</a>.</p>', 'google-places-reviews' ), esc_url( 'https://code.google.com/apis/console/?noredirect' ), esc_url( 'https://developers.google.com/places/documentation/#Authentication' ), admin_url( '/options-general.php?page=googleplacesreviews' ) ); 
  328. $this->output_error_message( $api_key_error, 'error' ); 
  329.  
  330. return; 
  331.  
  332. //loop through options array and save options to new instance 
  333. foreach ( $this->widget_fields as $field => $value ) { 
  334. ${$field} = ! isset( $instance[ $field ] ) ? $value : esc_attr( $instance[ $field ] ); 
  335. //Get the widget form 
  336. include( GPR_PLUGIN_PATH . '/inc/widget-form.php' ); 
  337.  
  338.  
  339.  
  340.  
  341. /** 
  342. * cURL (wp_remote_get) the Google Places API 
  343. * @description: CURLs the Google Places API with our url parameters and returns JSON response 
  344. * @param $url 
  345. * @return array|mixed 
  346. */ 
  347. function get_reviews( $url ) { 
  348.  
  349. //Sanitize the URL 
  350. $url = esc_url_raw( $url ); 
  351.  
  352. // Send API Call using WP's HTTP API 
  353. $data = wp_remote_get( $url ); 
  354.  
  355. if ( is_wp_error( $data ) ) { 
  356. $error_message = $data->get_error_message(); 
  357. $this->output_error_message( "Something went wrong: $error_message", 'error' ); 
  358.  
  359. //Use curl only if necessary 
  360. if ( empty( $data['body'] ) ) { 
  361.  
  362. $ch = curl_init( $url ); 
  363. curl_setopt( $ch, CURLOPT_RETURNTRANSFER, true ); 
  364. curl_setopt( $ch, CURLOPT_HEADER, 0 ); 
  365. $data = curl_exec( $ch ); // Google response 
  366. curl_close( $ch ); 
  367. $response = json_decode( $data, true ); 
  368.  
  369. } else { 
  370. $response = json_decode( $data['body'], true ); 
  371.  
  372. //Get Reviewers Avatars 
  373. $response = $this->get_reviewers_avatars( $response ); 
  374.  
  375. //Get Business Avatar 
  376. $response = $this->get_business_avatar( $response ); 
  377.  
  378.  
  379. //Google response data in JSON format 
  380. return $response; 
  381.  
  382.  
  383. /** 
  384. * Get Reviewers Avatars 
  385. * Get avatar from Places API response or provide placeholder. 
  386. * @return array 
  387. */ 
  388. function get_reviewers_avatars( $response ) { 
  389. // GPR Reviews Array. 
  390. $gpr_reviews = array(); 
  391.  
  392. // Includes Avatar image from user. 
  393. if ( isset( $response['result']['reviews'] ) && ! empty( $response['result']['reviews'] ) ) { 
  394.  
  395. // Loop Google Places reviews. 
  396. foreach ( $response['result']['reviews'] as $review ) { 
  397. // Check to see if image is empty (no broken images). 
  398. if ( ! empty( $review['profile_photo_url'] ) ) { 
  399. $avatar_img = $review['profile_photo_url'] . '?sz=100'; 
  400. } else { 
  401. $avatar_img = GPR_PLUGIN_URL . '/assets/images/mystery-man.png'; 
  402.  
  403. // Add array image to review array. 
  404. $review = array_merge( $review, array( 'avatar' => $avatar_img ) ); 
  405. // Add full review to $gpr_views. 
  406. array_push( $gpr_reviews, $review ); 
  407.  
  408. // Merge custom reviews array with response. 
  409. $response = array_merge( $response, array( 'gpr_reviews' => $gpr_reviews ) ); 
  410.  
  411. return $response; 
  412.  
  413. /** 
  414. * Get Business Avatar 
  415. * @description: Gets the business Avatar and 
  416. * @return array 
  417. */ 
  418. function get_business_avatar( $response ) { 
  419.  
  420. //Business Avatar 
  421. if ( isset( $response['result']['photos'] ) ) { 
  422.  
  423. $request_url = add_query_arg( 
  424. array( 
  425. 'photoreference' => $response['result']['photos'][0]['photo_reference'],  
  426. 'key' => $this->api_key,  
  427. 'maxwidth' => '300',  
  428. 'maxheight' => '300',  
  429. ),  
  430. 'https://maps.googleapis.com/maps/api/place/photo' 
  431. ); 
  432.  
  433. $response = array_merge( $response, array( 'place_avatar' => esc_url( $request_url ) ) ); 
  434.  
  435.  
  436. return $response; 
  437.  
  438.  
  439. /** 
  440. * Enqueue Widget Theme Scripts 
  441. * Outputs the necessary scripts for the widget themes 
  442. * @param $widget_style 
  443. */ 
  444. function enqueue_widget_theme_scripts( $widget_style ) { 
  445.  
  446. $suffix = defined( 'SCRIPT_DEBUG' ) && SCRIPT_DEBUG ? '' : '.min'; 
  447.  
  448. //Determine which CSS to pull 
  449. $css_raised = GPR_PLUGIN_URL . '/assets/css/gpr-theme-raised' . $suffix . '.css'; 
  450. $css_minimal = GPR_PLUGIN_URL . '/assets/css/gpr-theme-minimal' . $suffix . '.css'; 
  451. $css_shadow = GPR_PLUGIN_URL . '/assets/css/gpr-theme-shadow' . $suffix . '.css'; 
  452. $css_inset = GPR_PLUGIN_URL . '/assets/css/gpr-theme-inset' . $suffix . '.css'; 
  453.  
  454. if ( $widget_style === 'Minimal Light' || $widget_style === 'Minimal Dark' ) { 
  455. //enqueue theme style 
  456. wp_register_style( 'grp_widget_style_minimal', $css_minimal ); 
  457. wp_enqueue_style( 'grp_widget_style_minimal' ); 
  458. if ( $widget_style === 'Shadow Light' || $widget_style === 'Shadow Dark' ) { 
  459. wp_register_style( 'grp_widget_style_shadow', $css_shadow ); 
  460. wp_enqueue_style( 'grp_widget_style_shadow' ); 
  461. if ( $widget_style === 'Inset Light' || $widget_style === 'Inset Dark' ) { 
  462. wp_register_style( 'grp_widget_style_inset', $css_inset ); 
  463. wp_enqueue_style( 'grp_widget_style_inset' ); 
  464. if ( $widget_style === 'Raised Light' || $widget_style === 'Raised Dark' ) { 
  465. wp_register_style( 'grp_widget_style_raised', $css_raised ); 
  466. wp_enqueue_style( 'grp_widget_style_raised' ); 
  467.  
  468.  
  469.  
  470. /** 
  471. * Output Error Message 
  472. * @param $message 
  473. * @param $style 
  474. */ 
  475. function output_error_message( $message, $style ) { 
  476.  
  477. switch ( $style ) { 
  478. case 'error' : 
  479. $style = 'gpr-error'; 
  480. break; 
  481. case 'warning' : 
  482. $style = 'gpr-warning'; 
  483. break; 
  484. default : 
  485. $style = 'gpr-warning'; 
  486.  
  487. $output = '<div class="gpr-alert ' . $style . '">'; 
  488. $output .= $message; 
  489. $output .= '</div>'; 
  490.  
  491. echo $output; 
  492.  
  493.  
  494. /** 
  495. * Get Star Rating 
  496. * Returns the necessary output for Google Star Ratings 
  497. * @param $rating 
  498. * @param $unix_timestamp 
  499. * @param $hide_out_of_rating 
  500. * @param $hide_google_image 
  501. * @return string 
  502. */ 
  503. function get_star_rating( $rating, $unix_timestamp, $hide_out_of_rating, $hide_google_image ) { 
  504.  
  505. $output = ''; 
  506. $rating_value = '<p class="gpr-rating-value" ' . ( ( $hide_out_of_rating === '1' ) ? ' style="display:none;"' : '' ) . '><span>' . $rating . '</span>' . __( ' out of 5 stars', 'google-places-reviews' ) . '</p>'; 
  507. $is_gpr_header = true; 
  508.  
  509. //AVATAR 
  510. $google_img = '<div class="gpr-google-logo-wrap"' . ( ( $hide_google_image === '1' ) ? ' style="display:none;"' : '' ) . '><img src="' . GPR_PLUGIN_URL . '/assets/images/google-logo-small.png' . '" class="gpr-google-logo-header" title=" ' . __( 'Reviewed from Google', 'google-places-reviews' ) . '" alt="' . __( 'Reviewed from Google', 'google-places-reviews' ) . '" /></div>'; 
  511.  
  512.  
  513. //Header doesn't have a timestamp 
  514. if ( $unix_timestamp ) { 
  515. $is_gpr_header = false; 
  516.  
  517. //continue with output 
  518.  
  519. $output .= '<div class="star-rating-wrap">'; 
  520. $output .= '<div class="star-rating-size" style="width:' . ( 65 * $rating / 5 ) . 'px;"></div>'; 
  521. $output .= '</div>'; 
  522.  
  523. //Output rating next to stars for individual reviews 
  524. if ( $is_gpr_header === false ) { 
  525. $output .= $rating_value; 
  526.  
  527. //Show timestamp for reviews 
  528. if ( $unix_timestamp ) { 
  529. $output .= '<span class="gpr-rating-time">' . $this->get_time_since( $unix_timestamp ) . '</span>'; 
  530.  
  531. //Show overall rating value of review 
  532. if ( $is_gpr_header === true ) { 
  533.  
  534. //Google logo 
  535. if ( isset( $hide_google_image ) && $hide_google_image !== 1 ) { 
  536.  
  537. $output .= $google_img; 
  538.  
  539. $output .= $rating_value; 
  540.  
  541.  
  542. return $output; 
  543.  
  544.  
  545. /** 
  546. * Time Since 
  547. * Works out the time since the entry post, takes a an argument in unix time (seconds) 
  548. */ 
  549. static public function get_time_since( $date, $granularity = 1 ) { 
  550. $difference = time() - $date; 
  551. $retval = ''; 
  552. $periods = array( 
  553. 'decade' => 315360000,  
  554. 'year' => 31536000,  
  555. 'month' => 2628000,  
  556. 'week' => 604800,  
  557. 'day' => 86400,  
  558. 'hour' => 3600,  
  559. 'minute' => 60,  
  560. 'second' => 1 
  561. ); 
  562.  
  563. foreach ( $periods as $key => $value ) { 
  564. if ( $difference >= $value ) { 
  565. $time = floor( $difference / $value ); 
  566. $difference %= $value; 
  567. $retval .= ( $retval ? ' ' : '' ) . $time . ' '; 
  568. $retval .= ( ( $time > 1 ) ? $key . 's' : $key ); 
  569. $granularity --; 
  570. if ( $granularity == '0' ) { 
  571. break; 
  572.  
  573. return ' posted ' . $retval . ' ago'; 
  574.  
  575. /** 
  576. * AJAX Clear Widget Cache 
  577. */ 
  578. public function clear_widget_cache() { 
  579.  
  580. if ( isset( $_POST['transient_id_1'] ) && isset( $_POST['transient_id_2'] ) ) { 
  581.  
  582. delete_transient( $_POST['transient_id_1'] ); 
  583. delete_transient( $_POST['transient_id_2'] ); 
  584. echo __( 'Cache cleared', 'google-places-reviews' ); 
  585.  
  586. } else { 
  587. echo __( 'Error: Transient ID not set. Cache not cleared.', 'google-places-reviews' ); 
  588.  
  589. wp_die(); 
  590.  
  591.  
  592. /** 
  593. * Delete Transient Cache 
  594. * Removes the transient cache when an error is displayed as to not cache error results 
  595. */ 
  596. function delete_transient_cache( $transient_unique_id ) { 
  597. delete_transient( 'gpr_widget_api_' . $transient_unique_id ); 
  598. delete_transient( 'gpr_widget_options_' . $transient_unique_id ); 
  599.