Skip to content

Commit 985ea60

Browse files
authored
Merge pull request #86 from n49/slider_v1.1.15
Slider v1.1.15
2 parents 69daa02 + cd9bf84 commit 985ea60

5 files changed

Lines changed: 168 additions & 59 deletions

File tree

CLAUDE.md

Lines changed: 48 additions & 56 deletions
Original file line numberDiff line numberDiff line change
@@ -1,47 +1,60 @@
11
# CLAUDE.md
22

3+
This file provides guidance to Claude Code (claude.ai/code) when working with code in this repository.
4+
35
Be extremely concise in all interactions.
46

57
## Overview
68

7-
WordPress plugin for embedding OPIO review feeds and sliders on client websites. Displays reviews from op.io aggregation service.
9+
WordPress plugin ("Widget for OPIO Reviews") for embedding OPIO review feeds and sliders on client websites. Displays reviews from the op.io aggregation service. Current version: **1.1.15**.
10+
11+
## Build & Development
12+
13+
**No build system exists.** No package.json, composer.json, webpack, gulp, or linting configs. Assets (JS/CSS) are edited directly.
14+
15+
**Testing:** No automated tests. Manual testing only via WordPress admin preview.
16+
17+
**Deployment:** GitHub Actions (`.github/workflows/main.yml`) deploys to WordPress.org SVN on git tag push using `10up/action-wordpress-plugin-deploy`. Slug: `widget-for-opio-reviews`.
18+
19+
**Version bump checklist** — update all three locations when releasing:
20+
1. `opio.php``Version:` in plugin header comment
21+
2. `opio.php``OPIO_PLUGIN_VERSION` constant
22+
3. `readme.txt``Stable tag:`
823

9-
**Plugin Name:** Widget for OPIO Reviews
10-
**Version:** 1.1.11
24+
**Debug mode:** Set WP option `opio_debug_mode` to `'1'` to load unminified assets from `assets/src/` instead of `assets/`.
1125

1226
## Architecture
1327

28+
### Initialization Flow
29+
30+
```
31+
opio.php → autoloader.php (PSR-4 for WP_Opio_Reviews\Includes)
32+
→ Plugin::register() on plugins_loaded
33+
→ Assets, Post_Types (opio_feed, opio_slider CPTs)
34+
→ Feed_Deserializer → Feed_Page, Builder_Page, Feed_Shortcode
35+
→ Slider_Deserializer → Slider_Feed_Page, Review_Slider, Slider_Shortcode
36+
→ Admin services (only when is_admin())
37+
```
38+
1439
### Two Rendering Modes
1540

16-
1. **Feed Shortcode** (`[opio_feed id='X']`)
17-
- Fetches pre-rendered HTML from `feed.op.io`
18-
- No local review rendering - just displays server HTML
19-
- File: `includes/class-feed-shortcode.php`
41+
1. **Feed** (`[opio_feed id='X']`) — Fetches pre-rendered HTML from `feed.op.io`, injects schema into `<head>` via output buffering. Handler: `class-feed-shortcode.php`.
42+
43+
2. **Slider** (`[opio_slider id='X']`) — Fetches JSON from `op.io/api/entities/reviews-slider`, renders locally via PHP templates. Three layout variants (horizontal, horizontal-carousel, vertical), each with public + admin-preview templates in `includes/`.
2044

21-
2. **Slider Widgets** (review carousels)
22-
- Fetches JSON from `op.io/api/entities/reviews-slider`
23-
- Renders reviews locally in PHP templates
24-
- 6 template files (3 public + 3 admin previews):
25-
- `reviews-slider-horizontal-template.php`
26-
- `reviews-slider-horizontal-carousel-template.php`
27-
- `reviews-slider-vertical-template.php`
28-
- `admin-reviews-slider-*` (admin preview versions)
45+
### Data Storage
2946

30-
### Key Files
47+
Widget settings are stored as JSON in `post_content` of custom post types (`opio_feed`, `opio_slider`). Serializers validate and save form data; deserializers retrieve and process it (RGBA→hex conversion, `wp_kses` allowlist filtering).
3148

32-
- `opio.php` - Plugin entry point
33-
- `includes/class-plugin.php` - Plugin initialization
34-
- `includes/class-feed-shortcode.php` - Feed shortcode handler
35-
- `includes/class-review-slider.php` - Slider widget handler
36-
- `includes/class-opio-handler.php` - API communication
37-
- `assets/js/opio-main.js` - Feed JS functions
38-
- `assets/js/opio-slider-main.js` - Slider JS functions (lightbox, slick carousel)
49+
### Asset Loading
3950

40-
### External Dependencies
51+
`class-assets.php` registers all CSS/JS. Debug mode toggle (`opio_debug_mode` option) switches between `assets/` and `assets/src/` paths. Bundled vendor libs: Slick Carousel, Moment.js, jQuery fallback (if WP jQuery unavailable).
4152

42-
- Slick Carousel (bundled)
43-
- Moment.js (bundled)
44-
- jQuery (WordPress)
53+
**Known issue:** `assets/css/public-main.css` and `public-main-rtl.css` are 0 bytes — styles only work in debug mode loading from `assets/src/css/`.
54+
55+
### REST API
56+
57+
Single endpoint: `GET /opioreviews/v1/get_businesses?orgID={id}` — proxies to `op.io/api/organizations/landingpageUsername`.
4558

4659
## API Endpoints
4760

@@ -52,35 +65,14 @@ WordPress plugin for embedding OPIO review feeds and sliders on client websites.
5265

5366
## Media Handling
5467

55-
Current support:
56-
- `rev.images[]` - array of `{imageId}` objects
57-
- `rev.videos[]` - array of `{videoId}` objects
58-
59-
NOT yet supported:
60-
- `rev.embeds[]` - social media embeds (YouTube, etc.)
61-
62-
### JS Functions
63-
64-
In `opio-main.js` (feeds):
65-
- `displayLargeImage(imageId, revId)` - shows large image (has bugs: fixed height, cover mode)
66-
- `addReview()` - builds review HTML dynamically
67-
68-
In `opio-slider-main.js` (sliders):
69-
- `displayLargeImage(imageId, revId)` - different implementation for lightbox
70-
- `openPhotoLightbox(reviewData)` - opens review detail modal
71-
- `hideLargeImage(revId)` - closes large image view
72-
73-
## Shortcodes
74-
75-
```php
76-
[opio_feed id='123'] // Review feed
77-
[opio_slider id='456'] // Review slider
78-
```
79-
80-
## Testing
68+
Supported: `rev.images[]` (imageId objects), `rev.videos[]` (videoId objects).
69+
Not yet supported: `rev.embeds[]` (social media embeds).
8170

82-
No automated tests. Manual testing via WordPress admin preview.
71+
JS lightbox/gallery functions exist in both `opio-main.js` (feeds) and `opio-slider-main.js` (sliders) with separate implementations.
8372

84-
## Deployment
73+
## Conventions
8574

86-
Plugin distributed via WordPress plugin directory or direct ZIP upload.
75+
- **Namespace:** `WP_Opio_Reviews\Includes` with PSR-4 autoloading
76+
- **File naming:** `class-{name}.php` maps to `Class_Name`
77+
- **Methods/functions:** `snake_case`
78+
- **Security:** `wp_verify_nonce()` for forms, `sanitize_text_field()` for input, `wp_kses()` with allowlist for output, `esc_url()`/`esc_html()` for escaping
Lines changed: 114 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,114 @@
1+
<?php
2+
3+
namespace WP_Opio_Reviews\Includes;
4+
5+
/**
6+
* Optimized feed shortcode [opio_feed_optimized id='X']
7+
*
8+
* Completely isolated from Feed_Shortcode / Opio_Handler.
9+
* Hits the -optimized routes on feed.op.io which return identical output
10+
* but with smaller HTML (external JS, consolidated CSS, minimal JSON embeds).
11+
*
12+
* Only the "all" review_option has optimized routes:
13+
* - allReviewFeed-optimized?entId={id}
14+
* - multiReviewFeed/allReviews-optimized?orgId={id}
15+
*
16+
* The "opio" review_option falls back to standard routes (no optimized variant).
17+
*/
18+
class Feed_Optimized_Shortcode {
19+
20+
private $feed_deserializer;
21+
22+
public function __construct(Feed_Deserializer $feed_deserializer) {
23+
$this->feed_deserializer = $feed_deserializer;
24+
}
25+
26+
public function register() {
27+
add_shortcode('opio_feed_optimized', array($this, 'init'));
28+
}
29+
30+
/**
31+
* Build the feed.op.io URL for optimized routes.
32+
*/
33+
private function build_feed_url($biz_id, $org_id, $review_option, $review_type) {
34+
if ($review_option == 'opio') {
35+
// No optimized variant for opio — use standard routes
36+
if ($review_type == 'orgfeed') {
37+
return "https://feed.op.io/multiReviewFeed?orgId=${org_id}&schema_enabled=true&schema_type=Local%20Business";
38+
}
39+
if ($review_type == 'single') {
40+
return "https://feed.op.io/reviewFeed?entityid=${biz_id}";
41+
}
42+
return "https://feed.op.io/reviewFeed?entId=${biz_id}";
43+
}
44+
45+
// "all" review_option — use optimized routes
46+
if ($review_type == 'orgfeed') {
47+
return "https://feed.op.io/multiReviewFeed/allReviews-optimized?orgId=${org_id}&schema_enabled=true&schema_type=Local%20Business";
48+
}
49+
return "https://feed.op.io/allReviewFeed-optimized?entId=${biz_id}";
50+
}
51+
52+
/**
53+
* Fetch HTML from feed.op.io.
54+
*/
55+
private function fetch_feed($url) {
56+
$response = wp_remote_get($url);
57+
if (is_wp_error($response)) {
58+
return null;
59+
}
60+
$body = wp_remote_retrieve_body($response);
61+
if (empty($body)) {
62+
return null;
63+
}
64+
return $body;
65+
}
66+
67+
public function init($atts) {
68+
if (get_option('opio_active') === '0') {
69+
return '';
70+
}
71+
72+
$feed = $this->feed_deserializer->get_feed($atts['id']);
73+
if ($feed == null) {
74+
return '';
75+
}
76+
77+
$feed_object = json_decode($feed->post_content);
78+
if (!$feed_object) {
79+
return '';
80+
}
81+
82+
$biz_id = isset($feed_object->biz_id) ? $feed_object->biz_id : '';
83+
$org_id = isset($feed_object->org_id) ? $feed_object->org_id : '';
84+
$review_type = isset($feed_object->review_type) ? $feed_object->review_type : '';
85+
$review_option = isset($feed_object->review_option) ? $feed_object->review_option : '';
86+
87+
// Validate IDs
88+
$valid = preg_match('/^[a-zA-Z0-9]{15,20}$/', $biz_id)
89+
|| preg_match('/^[a-zA-Z0-9]{15,20}$/', $org_id);
90+
if (!$valid) {
91+
return '';
92+
}
93+
94+
$url = $this->build_feed_url($biz_id, $org_id, $review_option, $review_type);
95+
$reviews = $this->fetch_feed($url);
96+
if ($reviews === null) {
97+
return '';
98+
}
99+
100+
ob_start();
101+
102+
echo '<div data-nitro-exclude="all" data-nitro-ignore="true" data-nitro-no-optimize="true" data-nitro-preserve-ws="true">';
103+
104+
$entity_id = !empty($biz_id) ? $biz_id : $org_id;
105+
if (!empty($entity_id)) {
106+
echo '<script>window.opioEntityId = "' . esc_js($entity_id) . '";</script>';
107+
}
108+
109+
echo $reviews;
110+
echo '</div>';
111+
112+
return ob_get_clean();
113+
}
114+
}

includes/class-plugin.php

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -100,6 +100,9 @@ public function register_services() {
100100
$feed_shortcode = new Feed_Shortcode($feed_deserializer);
101101
$feed_shortcode->register();
102102

103+
$feed_optimized_shortcode = new Feed_Optimized_Shortcode($feed_deserializer);
104+
$feed_optimized_shortcode->register();
105+
103106
$slider_shortcode = new Slider_Shortcode($slider_deserializer);
104107
$slider_shortcode->register();
105108

opio.php

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -3,7 +3,7 @@
33
Plugin Name: Widget for OPIO Reviews
44
Plugin URI:
55
Description: Instantly add OPIO Reviews on your website to increase user confidence and SEO.
6-
Version: 1.1.14
6+
Version: 1.1.15
77
Author: Dhiraj Timalsina <dhiraj@n49.com>
88
Text Domain: widget-for-opio-reviews
99
Domain Path: /languages
@@ -22,7 +22,7 @@
2222

2323
require(ABSPATH . 'wp-includes/version.php');
2424

25-
define('OPIO_PLUGIN_VERSION' , '1.1.14');
25+
define('OPIO_PLUGIN_VERSION' , '1.1.15');
2626
define('OPIO_PLUGIN_FILE' , __FILE__);
2727
define('OPIO_PLUGIN_URL' , plugins_url(basename(plugin_dir_path(__FILE__ )), basename(__FILE__)));
2828
define('OPIO_ASSETS_URL' , OPIO_PLUGIN_URL . '/assets/');

readme.txt

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,7 @@
22
Author: Dhiraj Timalsina
33
Tags: Widget for OPIO Reviews, opio, reviews, rating, widget, google business, testimonials
44
Tested up to: 6.4
5-
Stable tag: 1.1.14
5+
Stable tag: 1.1.15
66
License: GPLv2 or later
77
License URI: http://www.gnu.org/licenses/gpl-2.0.html
88

0 commit comments

Comments
 (0)