From ba1e1ccf869b818f7a7a897264dfea05563a7796 Mon Sep 17 00:00:00 2001
From: Jake Vanderwerf <get@jakevanderwerf.ca>
Date: Sun, 07 Jun 2026 20:10:20 +0000
Subject: [PATCH] =Major overhaul of Integrations. Playing around with adding fields to post types through Registrar from an integrations' class file.
---
inc/managers/Notifications/Notifications.php | 10
inc/managers/SEO/render/SchemaOutput.php | 2
jvb.php | 50 +++++
inc/rest/routes/NotificationsRoutes.php | 2
inc/registrar/config/Integration.php | 8
inc/admin/ContentTaxonomy.php | 4
inc/managers/DashboardManager.php | 15 +
inc/registrar/helpers/MakeTimelineType.php | 4
inc/managers/CRUDManager.php | 11
inc/managers/RoleManager.php | 8
inc/rest/routes/FeedRoutes.php | 8
assets/js/min/favourites.min.js | 2
inc/rest/routes/ApprovalRoutes.php | 4
inc/managers/_setup.php | 8
inc/blocks/RegisterBlocks.php | 4
JVBase.php | 8
inc/managers/LoginManager.php | 3
inc/integrations/Square.php | 85 +++-----
inc/managers/Notifications/EmailDigests.php | 8
base/Site.php | 4
inc/integrations/Integrations.php | 11 +
inc/integrations/Facebook.php | 9 +
inc/integrations/Instagram.php | 3
inc/managers/DirectoryManager.php | 6
inc/registrar/Registrar.php | 68 ++++++-
activate.php | 4
assets/js/concise/FrontendFavourites.js | 3
inc/registrar/helpers/MakeCalendarType.php | 9
inc/blocks/_setup.php | 8
inc/rest/routes/ContentTermsRoutes.php | 2
inc/helpers/dashboard.php | 4
inc/blocks/FAQBlock.php | 2
inc/rest/_setup.php | 4
assets/js/concise/AuthManager.js | 1
assets/js/min/auth.min.js | 2
inc/registrar/config/Section.php | 13
inc/registrar/Fields.php | 2
inc/integrations/GoogleMyBusiness.php | 5
checks.php | 2
inc/registrar/fields/Field.php | 17 +
inc/registrar/helpers/AddIntegrationFields.php | 6
inc/managers/SEO/render/Thing/Product/Product.php | 7
inc/admin/_setup.php | 2
inc/managers/ApprovalManager.php | 2
inc/registrar/helpers/HideSingle.php | 7
inc/integrations/GoogleMaps.php | 2
inc/rest/Rest.php | 4
inc/rest/RestRouteManager.php | 4
inc/rest/routes/LoginRoutes.php | 31 +-
inc/managers/VerifyEntryManager.php | 2
inc/managers/InvitationsManager.php | 8
51 files changed, 321 insertions(+), 177 deletions(-)
diff --git a/JVBase.php b/JVBase.php
index f0b0c3d..28efe56 100644
--- a/JVBase.php
+++ b/JVBase.php
@@ -151,7 +151,7 @@
$this->managers['notifications'] = new NotificationManager();
$this->routes['notifications'] = new NotificationsRoutes();
}
- if (!empty(Registrar::getFeatured('approve_new'))) {
+ if (!empty(Registrar::withFeature('approve_new'))) {
$this->managers['approvals'] = new ApprovalManager();
}
if (Site::has('feed_block') || Site::has('dashboard')) {
@@ -183,13 +183,13 @@
if ($membership && $membership->has('invitable')) {
$this->managers['invitations'] = new InvitationsManager();
}
- if (!empty(Registrar::getFeatured('has_responses'))) {
+ if (!empty(Registrar::withFeature('has_responses'))) {
$this->routes['comments'] = new ResponseRoutes();
}
- if (!empty(Registrar::getFeatured('karma'))) {
+ if (!empty(Registrar::withFeature('karma'))) {
$this->routes['vote'] = new VoteRoutes();
}
- if (!empty(Registrar::getFeatured('karma'))
+ if (!empty(Registrar::withFeature('karma'))
|| ($membership && $membership->has('member_verified')) ||
($membership && $membership->has('term_approval'))) {
$this->routes['approvals'] = new ApprovalRoutes();
diff --git a/activate.php b/activate.php
index c76a65d..af0f7a1 100644
--- a/activate.php
+++ b/activate.php
@@ -64,7 +64,7 @@
$role = get_role('administrator');
$users = get_users(['role' => 'administrator']);
- foreach (array_merge(Registrar::getRegistered('post'), Registrar::getFeatured('is_content')) as $slug) {
+ foreach (array_merge(Registrar::getRegistered('post'), Registrar::withFeature('is_content')) as $slug) {
error_log('Adding administrative roles to '.$slug);
$plural = $roleManager->getContentPlural($slug);
$capabilities = [
@@ -105,7 +105,7 @@
$roleManager = new RoleManager();
$users = get_users(['role' => 'administrator']);
- foreach (array_merge(Registrar::getRegistered('post'), Registrar::getFeatured('is_content', 'term')) as $slug) {
+ foreach (array_merge(Registrar::getRegistered('post'), Registrar::withFeature('is_content', 'term')) as $slug) {
foreach ($users as $user) {
// These methods should check if post type exists before adding caps
diff --git a/assets/js/concise/AuthManager.js b/assets/js/concise/AuthManager.js
index ab70c92..12a4a5f 100644
--- a/assets/js/concise/AuthManager.js
+++ b/assets/js/concise/AuthManager.js
@@ -127,6 +127,7 @@
this.authenticated = authData.authenticated || false;
this.user = authData.user || false;
this.nonces = authData.nonces || {};
+ console.log(this.nonces);
// Session expired — was logged in, now isn't
if (wasAuthenticated && !this.authenticated) {
diff --git a/assets/js/concise/FrontendFavourites.js b/assets/js/concise/FrontendFavourites.js
index e016107..661bbfc 100644
--- a/assets/js/concise/FrontendFavourites.js
+++ b/assets/js/concise/FrontendFavourites.js
@@ -7,6 +7,9 @@
storeName: 'favourites',
keyPath: 'id',
endpoint: 'favourites',
+ headers: {
+ 'X-Action-Nonce': window.auth.getNonce('favourites')
+ },
indexes: [
{name: 'content', keyPath: 'content'},
{name: 'listId', keyPath: 'listId'},
diff --git a/assets/js/min/auth.min.js b/assets/js/min/auth.min.js
index 587eafa..daad9f4 100644
--- a/assets/js/min/auth.min.js
+++ b/assets/js/min/auth.min.js
@@ -1 +1 @@
-window.auth=new class{constructor(){this.initialized=!1,this.isAuthenticating=!1,this.authenticated=!1,this.user=!1,this.nonces={},this.subscribers=new Set,this.cacheExpiry=3e5,this.init()}async init(){if(!this.isAuthenticating){this.isAuthenticating=!0;try{if("undefined"!=typeof jvbAuth)return this.setAuthData(jvbAuth),this.initialized=!0,this.isAuthenticating=!1,void this.notify("auth-loaded",{fromCache:!1});await this.fetchAuth()}catch(t){this.clearAuthData(),this.initialized=!0,this.isAuthenticating=!1,this.notify("auth-error",{error:t})}}}async refreshNonce(t="wp_rest"){try{return await this.fetchAuth(),this.getNonce(t)}catch(t){return console.error("Failed to refresh nonce:",t),null}}async fetch(t,i={}){const e=async(s=0)=>{const h={...!(i.body instanceof FormData)&&{"Content-Type":"application/json"},...i.headers,"X-WP-Nonce":this.getNonce()},n=await fetch(t,{...i,credentials:"same-origin",headers:h});if((403===n.status||401===n.status)&&0===s){const t=await n.clone().json();if("rest_cookie_invalid_nonce"===t.code||t.message?.includes("Cookie check"))return console.log("Nonce invalid, refreshing auth..."),await this.refresh(),e(s+1)}return n};return e()}async fetchAuth(){const t=await fetch(`${jvbSettings.api}auth/status`,{method:"GET",credentials:"same-origin",headers:{"Content-Type":"application/json"}});if(!t.ok)throw new Error("Auth check failed");const i=await t.json();this.setAuthData(i),this.initialized=!0,this.isAuthenticating=!1,this.notify("auth-loaded",{fromCache:!1})}setAuthData(t){const i=this.initialized&&this.authenticated;this.authenticated=t.authenticated||!1,this.user=t.user||!1,this.nonces=t.nonces||{},i&&!this.authenticated&&(window.location.href=`/login?redirect_to=${encodeURIComponent(window.location.href)}`)}clearAuthData(){this.authenticated=!1,this.user=null,this.nonces={}}async refresh(){this.isAuthenticating=!0,this.initialized=!1;try{await this.fetchAuth(),this.notify("auth-refreshed",{})}catch(t){console.error("Failed to refresh auth:",t),this.clearAuthData(),this.initialized=!0,this.isAuthenticating=!1,this.notify("auth-error",{error:t})}}getNonce(t="wp_rest"){return this.nonces[t]||""}getUser(){return this.user}isAuthenticated(){return this.authenticated}async handleLogin(t=null){if(t)return this.setAuthData(t),this.initialized=!0,this.isAuthenticating=!1,void this.notify("auth-loaded",{fromCache:!1,fromLogin:!0});await this.refresh()}handleLogout(){this.clearAuthData(),this.notify("logged-out",{})}subscribe(t){return this.subscribers.add(t),this.initialized&&t("auth-loaded",{fromCache:!1,immediate:!0}),()=>this.subscribers.delete(t)}notify(t,i){this.subscribers.forEach((e=>{try{e(t,i)}catch(t){console.error("Subscriber error:",t)}}))}};
\ No newline at end of file
+window.auth=new class{constructor(){this.initialized=!1,this.isAuthenticating=!1,this.authenticated=!1,this.user=!1,this.nonces={},this.subscribers=new Set,this.cacheExpiry=3e5,this.init()}async init(){if(!this.isAuthenticating){this.isAuthenticating=!0;try{if("undefined"!=typeof jvbAuth)return this.setAuthData(jvbAuth),this.initialized=!0,this.isAuthenticating=!1,void this.notify("auth-loaded",{fromCache:!1});await this.fetchAuth()}catch(t){this.clearAuthData(),this.initialized=!0,this.isAuthenticating=!1,this.notify("auth-error",{error:t})}}}async refreshNonce(t="wp_rest"){try{return await this.fetchAuth(),this.getNonce(t)}catch(t){return console.error("Failed to refresh nonce:",t),null}}async fetch(t,i={}){const e=async(s=0)=>{const n={...!(i.body instanceof FormData)&&{"Content-Type":"application/json"},...i.headers,"X-WP-Nonce":this.getNonce()},h=await fetch(t,{...i,credentials:"same-origin",headers:n});if((403===h.status||401===h.status)&&0===s){const t=await h.clone().json();if("rest_cookie_invalid_nonce"===t.code||t.message?.includes("Cookie check"))return console.log("Nonce invalid, refreshing auth..."),await this.refresh(),e(s+1)}return h};return e()}async fetchAuth(){const t=await fetch(`${jvbSettings.api}auth/status`,{method:"GET",credentials:"same-origin",headers:{"Content-Type":"application/json"}});if(!t.ok)throw new Error("Auth check failed");const i=await t.json();this.setAuthData(i),this.initialized=!0,this.isAuthenticating=!1,this.notify("auth-loaded",{fromCache:!1})}setAuthData(t){const i=this.initialized&&this.authenticated;this.authenticated=t.authenticated||!1,this.user=t.user||!1,this.nonces=t.nonces||{},console.log(this.nonces),i&&!this.authenticated&&(window.location.href=`/login?redirect_to=${encodeURIComponent(window.location.href)}`)}clearAuthData(){this.authenticated=!1,this.user=null,this.nonces={}}async refresh(){this.isAuthenticating=!0,this.initialized=!1;try{await this.fetchAuth(),this.notify("auth-refreshed",{})}catch(t){console.error("Failed to refresh auth:",t),this.clearAuthData(),this.initialized=!0,this.isAuthenticating=!1,this.notify("auth-error",{error:t})}}getNonce(t="wp_rest"){return this.nonces[t]||""}getUser(){return this.user}isAuthenticated(){return this.authenticated}async handleLogin(t=null){if(t)return this.setAuthData(t),this.initialized=!0,this.isAuthenticating=!1,void this.notify("auth-loaded",{fromCache:!1,fromLogin:!0});await this.refresh()}handleLogout(){this.clearAuthData(),this.notify("logged-out",{})}subscribe(t){return this.subscribers.add(t),this.initialized&&t("auth-loaded",{fromCache:!1,immediate:!0}),()=>this.subscribers.delete(t)}notify(t,i){this.subscribers.forEach((e=>{try{e(t,i)}catch(t){console.error("Subscriber error:",t)}}))}};
\ No newline at end of file
diff --git a/assets/js/min/favourites.min.js b/assets/js/min/favourites.min.js
index 359b69b..8369985 100644
--- a/assets/js/min/favourites.min.js
+++ b/assets/js/min/favourites.min.js
@@ -1 +1 @@
-(()=>{class t{constructor(){let t=window.jvbStore.register("favourites",{storeName:"favourites",keyPath:"id",endpoint:"favourites",indexes:[{name:"content",keyPath:"content"},{name:"listId",keyPath:"listId"}],TTL:36e4,showLoading:!1,filters:{user:window.auth.getUser(),content:"all",order:"desc",orderby:"date",page:1,all:!0}});this.store=t.favourites,this.store.subscribe(((t,e)=>{t}))}toggleFavourite(t){if(!window.auth.getUser())return void(window.location.href=jvbSettings.redirect+"&action=register&type=favourites");t.classList.toggle("favourited");const e=t.classList.contains("favourited")?"add":"remove",o=t.classList.contains("favourited")?`Added ${t.dataset.type} to favourites.`:`Removed ${t.dataset.type} from favourites.`;window.jvbA11y.announce(o),t.innerHTML=jvbSettings.icons[t.classList.contains("favourited")?"heart-filled":"heart"],this.store.setItem(t.dataset.id,{target_id:t.dataset.id,action:e,type:t.dataset.type,artist:t.dataset.artist})}isFavourited(t,e){const o=`${this.userId}_${t}_${e}`;return void 0!==this.store.get(o)}}document.addEventListener("DOMContentLoaded",(function(){window.jvbFavourites=!1,window.auth.subscribe((e=>{"auth-loaded"===e&&(window.jvbFavourites=new t)}))})),window.toggleFavourite=function(t){window.jvbFavourites()?window.jvbFavourites.toggleFavourite(t):console.log("No Favourites Loaded")},window.isFavourited=function(t,e){if(window.jvbFavourites())return window.jvbFavourites.isFavourited(t,e);console.log("No Favourites Loaded")}})();
\ No newline at end of file
+(()=>{class t{constructor(){let t=window.jvbStore.register("favourites",{storeName:"favourites",keyPath:"id",endpoint:"favourites",headers:{"X-Action-Nonce":window.auth.getNonce("favourites")},indexes:[{name:"content",keyPath:"content"},{name:"listId",keyPath:"listId"}],TTL:36e4,showLoading:!1,filters:{user:window.auth.getUser(),content:"all",order:"desc",orderby:"date",page:1,all:!0}});this.store=t.favourites,this.store.subscribe(((t,e)=>{t}))}toggleFavourite(t){if(!window.auth.getUser())return void(window.location.href=jvbSettings.redirect+"&action=register&type=favourites");t.classList.toggle("favourited");const e=t.classList.contains("favourited")?"add":"remove",o=t.classList.contains("favourited")?`Added ${t.dataset.type} to favourites.`:`Removed ${t.dataset.type} from favourites.`;window.jvbA11y.announce(o),t.innerHTML=jvbSettings.icons[t.classList.contains("favourited")?"heart-filled":"heart"],this.store.setItem(t.dataset.id,{target_id:t.dataset.id,action:e,type:t.dataset.type,artist:t.dataset.artist})}isFavourited(t,e){const o=`${this.userId}_${t}_${e}`;return void 0!==this.store.get(o)}}document.addEventListener("DOMContentLoaded",(function(){window.jvbFavourites=!1,window.auth.subscribe((e=>{"auth-loaded"===e&&(window.jvbFavourites=new t)}))})),window.toggleFavourite=function(t){window.jvbFavourites()?window.jvbFavourites.toggleFavourite(t):console.log("No Favourites Loaded")},window.isFavourited=function(t,e){if(window.jvbFavourites())return window.jvbFavourites.isFavourited(t,e);console.log("No Favourites Loaded")}})();
\ No newline at end of file
diff --git a/base/Site.php b/base/Site.php
index e082012..43d194a 100644
--- a/base/Site.php
+++ b/base/Site.php
@@ -1,8 +1,6 @@
<?php
namespace JVBase\base;
-use JVBase\base\Login;
-
if (!defined('ABSPATH')) {
exit;
}
@@ -92,7 +90,7 @@
public static function getInstance():Site {
if (!isset(self::$instance)) {
self::$instance = new self();
- do_action('jvbLoadDefinitions');
+ do_action('jvb_define_site');
}
return self::$instance;
}
diff --git a/checks.php b/checks.php
index 6b55711..d968100 100644
--- a/checks.php
+++ b/checks.php
@@ -14,7 +14,7 @@
function jvbUserTypes():array
{
- return Registrar::getFeatured('profile_link', 'user');
+ return Registrar::withFeature('profile_link', 'user');
}
diff --git a/inc/admin/ContentTaxonomy.php b/inc/admin/ContentTaxonomy.php
index 399d3ac..0863a1e 100644
--- a/inc/admin/ContentTaxonomy.php
+++ b/inc/admin/ContentTaxonomy.php
@@ -17,7 +17,7 @@
{
public function __construct()
{
- if (empty(Registrar::getFeatured('is_content', 'term'))){
+ if (empty(Registrar::withFeature('is_content', 'term'))){
return;
}
add_filter(BASE.'handle_bulk_operation', [ $this, 'processOperation' ], 10, 3);
@@ -124,7 +124,7 @@
</thead>
<tbody>
<?php
- $taxonomies = Registrar::getFeatured('is_content', 'term');
+ $taxonomies = Registrar::withFeature('is_content', 'term');
foreach ($taxonomies as $slug):
$registrar = Registrar::getInstance($slug);
$taxonomy = BASE . $slug;
diff --git a/inc/admin/_setup.php b/inc/admin/_setup.php
index 6ae125f..31d7b6c 100644
--- a/inc/admin/_setup.php
+++ b/inc/admin/_setup.php
@@ -8,7 +8,7 @@
add_action('init', 'jvb_maybe_setup_content_taxonomy', 1);
function jvb_maybe_setup_content_taxonomy(): void
{
- if (!empty(Registrar::getFeatured('is_content', 'term'))) {
+ if (!empty(Registrar::withFeature('is_content', 'term'))) {
require(JVB_DIR . '/inc/admin/ContentTaxonomy.php');
}
}
diff --git a/inc/blocks/FAQBlock.php b/inc/blocks/FAQBlock.php
index 81e3db9..fd6d84d 100644
--- a/inc/blocks/FAQBlock.php
+++ b/inc/blocks/FAQBlock.php
@@ -32,7 +32,7 @@
);
- $faq = array_values(Registrar::getFeatured('is_faq','post'));
+ $faq = array_values(Registrar::withFeature('is_faq','post'));
$registrar = Registrar::getInstance($faq[0]);
$this->section = array_map('jvbCheckBase', $registrar->registrar->taxonomies)[0];
$this->postType = $registrar->getBased();
diff --git a/inc/blocks/RegisterBlocks.php b/inc/blocks/RegisterBlocks.php
index e9811ff..efe6e51 100644
--- a/inc/blocks/RegisterBlocks.php
+++ b/inc/blocks/RegisterBlocks.php
@@ -14,7 +14,7 @@
require(JVB_DIR . '/build/summary/render.php');
require(JVB_DIR . '/build/forms/render.php');
require(JVB_DIR . '/build/menu/render.php');
-if (!empty(Registrar::getFeatured('is_glossary'))) {
+if (!empty(Registrar::withFeature('is_glossary'))) {
error_log('Has Glossary Type');
require(JVB_DIR . '/build/glossary/render.php');
}
@@ -39,7 +39,7 @@
// ]
// );
// }
- if (!empty(Registrar::getFeatured('show_directory'))) {
+ if (!empty(Registrar::withFeature('show_directory'))) {
register_block_type(
JVB_DIR . '/build/list',
[
diff --git a/inc/blocks/_setup.php b/inc/blocks/_setup.php
index cdae9f1..42ec61d 100644
--- a/inc/blocks/_setup.php
+++ b/inc/blocks/_setup.php
@@ -20,17 +20,17 @@
new JVBase\blocks\MenuBlock();
}
- if (!empty(Registrar::getFeatured('is_faq'))) {
+ if (!empty(Registrar::withFeature('is_faq'))) {
require('FAQBlock.php');
new JVBase\blocks\FAQBlock();
}
- if (!empty(Registrar::getFeatured('is_glossary'))) {
+ if (!empty(Registrar::withFeature('is_glossary'))) {
require('GlossaryBlock.php');
new JVBase\blocks\GlossaryBlock();
}
- if (!empty(Registrar::getFeatured('is_timeline'))) {
+ if (!empty(Registrar::withFeature('is_timeline'))) {
require('TimelineBlock.php');
new JVBase\blocks\TimelineBlock();
}
@@ -47,7 +47,7 @@
// ]
// );
// }
-// if (!empty(Registrar::getFeatured('show_directory'))) {
+// if (!empty(Registrar::withFeature('show_directory'))) {
// error_log('Registering Directory List Block');
// register_block_type(
// JVB_DIR . '/build/list',
diff --git a/inc/helpers/dashboard.php b/inc/helpers/dashboard.php
index bd1b1ac..918200d 100644
--- a/inc/helpers/dashboard.php
+++ b/inc/helpers/dashboard.php
@@ -62,7 +62,7 @@
array_map(function ($role) {
return BASE.$role;
},
- Registrar::getFeatured('has_dashboard', 'user'))
+ Registrar::withFeature('has_dashboard', 'user'))
)
)>0;
}
@@ -109,7 +109,7 @@
}
}
- $types = Registrar::getFeatured('show_feed');
+ $types = Registrar::withFeature('show_feed');
$types = array_filter($temp, function ($type) use ($types) {
return in_array($type, $types);
});
diff --git a/inc/integrations/Facebook.php b/inc/integrations/Facebook.php
index 197ca61..e7d54e9 100644
--- a/inc/integrations/Facebook.php
+++ b/inc/integrations/Facebook.php
@@ -17,6 +17,15 @@
class Facebook extends Integrations
{
// Facebook-specific properties
+ protected array $allowedContent = [
+ 'post',
+ 'photo',
+ 'video',
+ 'event',
+ 'offer',
+ 'note',
+ 'milestone'
+ ];
private string $page_id = '';
private string $page_access_token = '';
private array $permissions = [];
diff --git a/inc/integrations/GoogleMaps.php b/inc/integrations/GoogleMaps.php
index 68d58fa..31a3d36 100644
--- a/inc/integrations/GoogleMaps.php
+++ b/inc/integrations/GoogleMaps.php
@@ -542,7 +542,7 @@
return true;
}
- if (!empty(Registrar::getFeatured('is_content', 'term')) && get_term_meta(get_queried_object_id(), BASE . 'has_map', true) === true) {
+ if (!empty(Registrar::withFeature('is_content', 'term')) && get_term_meta(get_queried_object_id(), BASE . 'has_map', true) === true) {
return true;
}
diff --git a/inc/integrations/GoogleMyBusiness.php b/inc/integrations/GoogleMyBusiness.php
index 9e86377..5893851 100644
--- a/inc/integrations/GoogleMyBusiness.php
+++ b/inc/integrations/GoogleMyBusiness.php
@@ -9,6 +9,11 @@
class GoogleMyBusiness extends Integrations
{
+ protected array $allowedContent = [
+ 'menu_item',
+ 'post',
+ 'event',
+ ];
private ?string $access_token = null;
protected string $readMask = 'name,title,storefrontAddress,metadata,openInfo,storeCode,categories,phoneNumbers,labels,specialHours';
private ?string $location = null;
diff --git a/inc/integrations/Instagram.php b/inc/integrations/Instagram.php
index 63910b1..4513381 100644
--- a/inc/integrations/Instagram.php
+++ b/inc/integrations/Instagram.php
@@ -17,6 +17,9 @@
class Instagram extends Integrations
{
+ protected array $allowedContent = [
+ 'post'
+ ];
private string $ig_user_id = '';
private string $page_id = '';
private string $page_access_token = '';
diff --git a/inc/integrations/Integrations.php b/inc/integrations/Integrations.php
index 7b32588..ef1a135 100644
--- a/inc/integrations/Integrations.php
+++ b/inc/integrations/Integrations.php
@@ -29,6 +29,15 @@
abstract class Integrations
{
/**
+ * Queue types
+ * These types match with IntegrationExecutor
+ */
+ protected static string $syncTo = 'sync_to';
+ protected static string $deleteFrom = 'delete_from';
+ protected static string $syncFrom = 'sync_from';
+ protected static string $syncCustomer = 'sync_customer';
+ protected static string $import = 'import';
+ /**
* API Configuration
* These properties define how the integration connects to external services
*/
@@ -319,7 +328,7 @@
if (!$taxonomies) {
// Combine both content and taxonomy filtering
$taxonomies = [];
- foreach (Registrar::getFeatured('is_content', 'term') as $type) {
+ foreach (Registrar::withFeature('is_content', 'term') as $type) {
$registrar = Registrar::getInstance($type);
if ($registrar->hasIntegration($this->service_name)) {
$taxonomies[] = $registrar->getSlug();
diff --git a/inc/integrations/Square.php b/inc/integrations/Square.php
index ba37b92..a6346f1 100644
--- a/inc/integrations/Square.php
+++ b/inc/integrations/Square.php
@@ -26,6 +26,14 @@
*/
class Square extends Integrations
{
+ protected array $allowedContent = [
+ 'REGULAR',
+ 'FOOD_AND_BEV',
+ 'APPOINTMENTS_SERVICE',
+ 'DIGITAL',
+ 'EVENT',
+ 'DONATION'
+ ];
/**
* Square API Configuration
*/
@@ -45,6 +53,9 @@
* OAuth Configuration
*/
protected bool $isOAuthService = true;
+
+ protected string $orderPostType = '_sq_order';
+ protected array $newOrder = [];
protected array $oauth = [
'authorize' => '',
'token' => '',
@@ -80,6 +91,11 @@
$this->refresh_interval = 7 * DAY_IN_SECONDS;
+ $this->newOrder = [
+ 'post_type' => $this->orderPostType,
+ 'post_status' => 'PROPOSED',
+ ];
+
// Define credential fields
$this->fields = [
'environment' => [
@@ -180,8 +196,7 @@
'sync_to_square' => 'Sync Site to Square',
]
);
-
- add_action('init', [$this, 'registerSquarePostTypes']);
+ add_action('init', [$this, 'registerSquarePostTypes'], 5);
}
/**
@@ -228,24 +243,20 @@
'square_order_id' => [
'type' => 'text',
'label' => 'Square Order ID',
- 'readonly' => true
],
'square_payment_id' => [
'type' => 'text',
'label' => 'Square Payment ID',
- 'readonly' => true
],
'square_customer_id' => [
'type' => 'text',
'label' => 'Square Customer ID',
- 'readonly' => true
],
'amount' => [
'type' => 'number',
'label' => 'Total Amount (cents)',
- 'readonly' => true
],
- 'status' => [
+ 'post_status' => [
'type' => 'select',
'label' => 'Order Status',
'options' => [
@@ -255,7 +266,6 @@
'COMPLETED' => 'Completed',
'CANCELED' => 'Canceled'
],
- 'readonly' => true
],
'fulfillment_status' => [
'type' => 'select',
@@ -268,7 +278,6 @@
'CANCELED' => 'Canceled',
'FAILED' => 'Failed'
],
- 'readonly' => true
],
'pickup_time' => [
'type' => 'datetime',
@@ -277,27 +286,22 @@
'customer_email' => [
'type' => 'email',
'label' => 'Customer Email',
- 'readonly' => true
],
'customer_name' => [
'type' => 'text',
'label' => 'Customer Name',
- 'readonly' => true
],
'customer_phone' => [
- 'type' => 'tel',
+ 'type' => 'phone',
'label' => 'Customer Phone',
- 'readonly' => true
],
'special_instructions' => [
'type' => 'textarea',
'label' => 'Special Instructions',
- 'readonly' => true
],
'items' => [
'type' => 'repeater',
'label' => 'Order Items',
- 'readonly' => true,
'fields' => [
'name' => ['type' => 'text', 'label' => 'Item Name'],
'quantity' => ['type' => 'number', 'label' => 'Quantity'],
@@ -308,17 +312,14 @@
'receipt_url' => [
'type' => 'url',
'label' => 'Receipt URL',
- 'readonly' => true
],
'created_at' => [
'type' => 'datetime',
'label' => 'Created At',
- 'readonly' => true
],
'updated_at' => [
'type' => 'datetime',
'label' => 'Last Updated',
- 'readonly' => true
]
];
}
@@ -327,16 +328,14 @@
{
$orders = Registrar::forPost('_sq_orders', 'Square Order', 'Square Orders');
$orders->make([
- 'public' => false
- ]
- );
+ 'public' => true
+ ]);
$orders->setAll(['system']);
$fields = $orders->fields();
foreach ($this->getOrderFields() as $fieldName => $config) {
$fields->addField($fieldName, $config);
}
-
}
/**
@@ -845,10 +844,9 @@
add_action('wp_login', [$this, 'trackUserLogin'], 10, 2);
add_action('wp_enqueue_scripts', [$this, 'enqueueScripts']);
- // Shared checkout UI (replaces outputCheckout)
add_filter('jvbAdditionalActions', [Checkout::class, 'render']);
- // Square-specific checkout description
+
add_filter('jvb_checkout_description', function (string $desc, string $provider) {
if ($provider === 'square') {
return 'Securely checkout with your name, email, and payments processed by Square.';
@@ -902,31 +900,31 @@
$queue = JVB()->queue();
$executor = new IntegrationExecutor();
- $queue->registry()->register('square_sync_to', new TypeConfig(
+ $queue->registry()->register(self::$syncTo, new TypeConfig(
executor: $executor,
chunkKey: 'items',
chunkSize: 50,
maxRetries: 3
));
- $queue->registry()->register('square_delete_from', new TypeConfig(
+ $queue->registry()->register(self::$deleteFrom, new TypeConfig(
executor: $executor,
chunkKey: 'external_ids',
chunkSize: 200,
maxRetries: 2
));
- $queue->registry()->register('square_sync_from', new TypeConfig(
+ $queue->registry()->register(self::$syncFrom, new TypeConfig(
executor: $executor,
maxRetries: 3
));
- $queue->registry()->register('square_sync_customer', new TypeConfig(
+ $queue->registry()->register(self::$syncCustomer, new TypeConfig(
executor: $executor,
maxRetries: 2
));
- $queue->registry()->register('square_import', new TypeConfig(
+ $queue->registry()->register(self::$import, new TypeConfig(
executor: $executor,
maxRetries: 3
));
@@ -941,7 +939,7 @@
*/
protected function handleTheSavePost(int $postID, \WP_Post $post, bool $update, array $settings): void
{
- $this->queueOperation('sync_to', [
+ $this->queueOperation(self::$syncTo, [
'items' => [$postID],
'user_id' => $this->userID,
], [
@@ -960,7 +958,7 @@
$square_id = get_post_meta($postID, BASE . '_square_catalog_id', true);
if ($square_id) {
- $this->queueOperation('delete_from', [
+ $this->queueOperation(self::$deleteFrom, [
'external_ids' => [$square_id],
'post_id' => $postID,
], [
@@ -970,26 +968,6 @@
}
/**
- * @deprecated IntegrationExecutor handles new operations via registerQueueTypes().
- * Kept for legacy-typed operations ('square_sync_to_square') already queued.
- * Safe to remove once all legacy operations have been processed.
- */
- public function processOperation(WP_Error|array $result, object $operation, array $data): WP_Error|array
- {
- $base = strtolower($this->service_name) . '_';
- $square = array_key_exists('user', $data) ? new self((int) $data['user']) : $this;
-
- return match ($operation->type) {
- $base . 'sync_to_square' => $square->processSyncToSquare($data),
- $base . 'delete_from_square' => $square->processDeleteFromSquare($data),
- $base . 'sync_from_square' => $square->processSyncFromSquare($data),
- $base . 'sync_customer' => $square->processSyncCustomer($data),
- default => $result,
- };
- }
-
-
- /**
* Process sync to Square
*/
private function processSyncToSquare(array $data): array
@@ -2764,17 +2742,18 @@
return [];
}
$array = $this->setBaseFields();
- return array_combine(
+ $return = array_combine(
array_map(fn($k) => 'sq_' . $k, array_keys($array)),
$array
);
+
+ return $return;
}
protected function setBaseFields():array
{
return [
'price' => [
'type' => 'number',
- 'bulkEdit' => true,
'label' => 'Price',
'step' => 0.01,
'max' => 99999,
diff --git a/inc/managers/ApprovalManager.php b/inc/managers/ApprovalManager.php
index 42200e0..38a4f3a 100644
--- a/inc/managers/ApprovalManager.php
+++ b/inc/managers/ApprovalManager.php
@@ -32,7 +32,7 @@
protected function defineTables():void
{
- $types = Registrar::getFeatured('approve_new');
+ $types = Registrar::withFeature('approve_new');
foreach ($types as $type) {
$requests = CustomTable::for("approval_{$type}_requests");
$registrar = Registrar::getInstance($type);
diff --git a/inc/managers/CRUDManager.php b/inc/managers/CRUDManager.php
index badcd6d..58aa17d 100644
--- a/inc/managers/CRUDManager.php
+++ b/inc/managers/CRUDManager.php
@@ -64,9 +64,14 @@
// Fields and sections
$this->skeleton->setFields($this->registrar->getFields());
- foreach ($this->registrar->getSections() as $config) {
- $this->skeleton->addSection($config['id'], $config);
- }
+ jvbDump($this->registrar->getSections());
+ $sections = $this->registrar->getSections();
+ if (count($sections) > 1) {
+ foreach ($sections as $config) {
+ jvbDump($config);
+ $this->skeleton->addSection($config['id'], $config);
+ }
+ }
// Taxonomies
$this->initTaxonomies();
diff --git a/inc/managers/DashboardManager.php b/inc/managers/DashboardManager.php
index 395e6c2..bb671e8 100644
--- a/inc/managers/DashboardManager.php
+++ b/inc/managers/DashboardManager.php
@@ -641,7 +641,10 @@
}
}
- return $icon;
+ return match($icon) {
+ 'favourites' => 'heart',
+ default => $icon
+ };
});
}
protected function getSlug(string $slug, string $page):string
@@ -744,7 +747,7 @@
//content types
$all = array_merge(
Registrar::getRegistered('post'),
- Registrar::getFeatured('is_content', 'term')
+ Registrar::withFeature('is_content', 'term')
);
$availableContent = array_filter($pages, function($page, $key) use($all) {
return !is_numeric($key) && in_array($key, $all) && JVB()->roles()->checkRole($this->user, $key);
@@ -1091,7 +1094,7 @@
<?php
$i=1;
$content = Registrar::getRegistered('post');
- $contentTax = Registrar::getFeatured('is_content', 'term');
+ $contentTax = Registrar::withFeature('is_content', 'term');
$taxonomies = Registrar::getRegistered('term');
foreach($contentTax as $index => $tax) {
unset($taxonomies[$index]);
@@ -1284,7 +1287,7 @@
$pages[] = 'Favourites';
}
- if (!empty(Registrar::getFeatured('karma'))) {
+ if (!empty(Registrar::withFeature('karma'))) {
$pages[] = 'Karmic Score';
}
@@ -1451,7 +1454,7 @@
foreach ($roles as $role) {
$contents = Registrar::getInstance($role)?->getCreatable();
if (!empty($contents)) {
- $hasKarma = Registrar::getFeatured('karma');
+ $hasKarma = Registrar::withFeature('karma');
$remove = empty(array_intersect($contents, $hasKarma));
}
}
@@ -1512,7 +1515,7 @@
*/
protected function getRolesWithDashboard():array
{
- return Registrar::getFeatured('has_dashboard', 'user');
+ return Registrar::withFeature('has_dashboard', 'user');
}
/**
diff --git a/inc/managers/DirectoryManager.php b/inc/managers/DirectoryManager.php
index 4645f97..ffe4843 100644
--- a/inc/managers/DirectoryManager.php
+++ b/inc/managers/DirectoryManager.php
@@ -90,21 +90,21 @@
$directories = [];
//content
- $content = Registrar::getFeatured('show_directory', 'post');
+ $content = Registrar::withFeature('show_directory', 'post');
if(!empty($content)) {
foreach ($content as $key) {
$directories[$key] = 'content';
}
}
- $taxonomies = Registrar::getFeatured('show_directory', 'term');
+ $taxonomies = Registrar::withFeature('show_directory', 'term');
if(!empty($taxonomies)) {
foreach ($taxonomies as $key) {
$directories[$key] = 'taxonomy';
}
}
- $users = Registrar::getFeatured('show_directory', 'user');
+ $users = Registrar::withFeature('show_directory', 'user');
if(!empty($users)) {
foreach ($users as $key) {
$directories[$key] = 'user';
diff --git a/inc/managers/InvitationsManager.php b/inc/managers/InvitationsManager.php
index c8d17a2..da6cec1 100644
--- a/inc/managers/InvitationsManager.php
+++ b/inc/managers/InvitationsManager.php
@@ -36,7 +36,7 @@
public function defineTable():void
{
- $terms = Registrar::getFeatured('invitable', 'term');
+ $terms = Registrar::withFeature('invitable', 'term');
$membership = Site::membership();
$roles = ($membership) ? Site::membership()->has('can_invite') :[];
if (empty($terms) && empty($roles)) {
@@ -163,9 +163,9 @@
}
// Term invitations from invitable content taxonomies
- $invitable = Registrar::getFeatured('invitable', 'term');
- $content = Registrar::getFeatured('is_content', 'term');
- $ownable = Registrar::getFeatured('is_ownable', 'term');
+ $invitable = Registrar::withFeature('invitable', 'term');
+ $content = Registrar::withFeature('is_content', 'term');
+ $ownable = Registrar::withFeature('is_ownable', 'term');
$taxonomies = array_intersect($invitable, $content, $ownable);
if (!empty($taxonomies)) {
$users = Registrar::getRegistered('user');
diff --git a/inc/managers/LoginManager.php b/inc/managers/LoginManager.php
index 39930db..5e0e37b 100644
--- a/inc/managers/LoginManager.php
+++ b/inc/managers/LoginManager.php
@@ -143,7 +143,7 @@
'hint' => 'Have a referral code? Paste it here!'
];
}
- $canRegister = Registrar::getFeatured('can_register', 'user');
+ $canRegister = Registrar::withFeature('can_register', 'user');
if (!empty($canRegister)) {
foreach ($canRegister as $role) {
$registrar = Registrar::getInstance($role);
@@ -456,6 +456,7 @@
protected function customStyles():void
{
$logo = get_theme_mod('custom_logo');
+ $small = $large = '';
if ($logo) {
$small = wp_get_attachment_image_src($logo, 'medium')[0]??'';
$large = wp_get_attachment_image_src($logo, 'large')[0]??'';
diff --git a/inc/managers/Notifications/EmailDigests.php b/inc/managers/Notifications/EmailDigests.php
index 8ab699e..841ffaf 100644
--- a/inc/managers/Notifications/EmailDigests.php
+++ b/inc/managers/Notifications/EmailDigests.php
@@ -43,7 +43,7 @@
protected function registerUserIndex():void
{
$table = CustomTable::for('user_notification_email_digest');
-// $types = implode(',',array_map(function($item) { return "'{$item}'"; }, Registrar::getFeatured('favouritable')));
+// $types = implode(',',array_map(function($item) { return "'{$item}'"; }, Registrar::withFeature('favouritable')));
$table->setColumns([
'id' => 'bigint(20) unsigned NOT NULL AUTO_INCREMENT',
'user_id' => "{$table->getUserIDType()} NOT NULL",
@@ -71,7 +71,7 @@
protected function registerTermIndex():void
{
$table = CustomTable::for('user_notification_email_digest');
- $types = implode(',',array_map(function($item) { return "'{$item}'"; }, Registrar::getFeatured('favouritable', 'term')));
+ $types = implode(',',array_map(function($item) { return "'{$item}'"; }, Registrar::withFeature('favouritable', 'term')));
$table->setColumns([
'id' => 'bigint(20) unsigned NOT NULL AUTO_INCREMENT',
'term_id' => "{$table->getTermIDType()} NOT NULL",
@@ -187,8 +187,8 @@
$content = '';
foreach ($subscription as $item) {
$temp = match ($item['item_type']) {
- array_merge(['user'], Registrar::getFeatured('favouritable', 'user')) => $this->getUserUpdates($item['item_id'], $frequency),
- Registrar::getFeatured('favouritable', 'term') => $this->getTermUpdates($item['item_id'], $item['item_type'], $frequency),
+ array_merge(['user'], Registrar::withFeature('favouritable', 'user')) => $this->getUserUpdates($item['item_id'], $frequency),
+ Registrar::withFeature('favouritable', 'term') => $this->getTermUpdates($item['item_id'], $item['item_type'], $frequency),
default => false,
};
if ($temp) {
diff --git a/inc/managers/Notifications/Notifications.php b/inc/managers/Notifications/Notifications.php
index 4700c1d..61ee88c 100644
--- a/inc/managers/Notifications/Notifications.php
+++ b/inc/managers/Notifications/Notifications.php
@@ -46,8 +46,8 @@
]
]);
}
- $contentTax = Registrar::getFeatured('is_content', 'term');
- $verifyEntry = Registrar::getFeatured('verify_entry', 'term');
+ $contentTax = Registrar::withFeature('is_content', 'term');
+ $verifyEntry = Registrar::withFeature('verify_entry', 'term');
if (!empty(array_intersect($contentTax, $verifyEntry))) {
$types = array_merge($types, [
'entry_requested' => [
@@ -69,7 +69,7 @@
]
]);
}
- $invitable = Registrar::getFeatured('invitable');
+ $invitable = Registrar::withFeature('invitable');
if (!empty($invitable)) {
$types = array_merge($types, [
'invitation_requested' => [
@@ -97,12 +97,12 @@
]);
}
- $approvals = Registrar::getFeatured('approve_new');
+ $approvals = Registrar::withFeature('approve_new');
if (!empty($approvals)) {
$tmp = ['user', 'term', 'post'];
$app = [];
foreach ($tmp as $t) {
- $approvals = Registrar::getFeatured('approve_new', $t);
+ $approvals = Registrar::withFeature('approve_new', $t);
if (!empty($approvals)) {
$app = array_merge($app, [
$t.'_new' => [
diff --git a/inc/managers/RoleManager.php b/inc/managers/RoleManager.php
index b275f12..a22b585 100644
--- a/inc/managers/RoleManager.php
+++ b/inc/managers/RoleManager.php
@@ -24,7 +24,7 @@
return strtolower(str_replace(' ', '_', $registrar->getPlural()??$registrar->getSingular().'s'));
},array_merge(
Registrar::getRegistered('post'),
- Registrar::getFeatured('is_content', 'term')
+ Registrar::withFeature('is_content', 'term')
));
add_action('set_user_role', [$this, 'updateRoles'], 10, 3);
@@ -470,7 +470,7 @@
protected function addAdminCaps():void
{
$users = get_users(['role' => 'administrator']);
- foreach (array_merge(Registrar::getRegistered('post'), Registrar::getFeatured('is_content')) as $slug) {
+ foreach (array_merge(Registrar::getRegistered('post'), Registrar::withFeature('is_content')) as $slug) {
$this->grantRoleCapabilities('administrator', $slug);
$this->grantRoleOthersCapabilities('administrator', $slug);
@@ -785,7 +785,7 @@
if ($ownable === null) {
$ownable = array_map(function ($instance) {
return $instance->slug;
- }, Registrar::getFeatured('is_ownable', 'term'));
+ }, Registrar::withFeature('is_ownable', 'term'));
}
return $ownable;
@@ -803,7 +803,7 @@
if ($invitable === null) {
$invitable = array_map(function ($instance) {
return $instance->slug;
- }, Registrar::getFeatured('invitable', 'term'));
+ }, Registrar::withFeature('invitable', 'term'));
}
return $invitable;
diff --git a/inc/managers/SEO/render/SchemaOutput.php b/inc/managers/SEO/render/SchemaOutput.php
index a6cdc55..25ac320 100644
--- a/inc/managers/SEO/render/SchemaOutput.php
+++ b/inc/managers/SEO/render/SchemaOutput.php
@@ -64,7 +64,7 @@
}
$isContent = array_values(array_filter(array_map(function($item) {
return intval(get_option(BASE.$item.'_archive', false));
- },Registrar::getFeatured('is_content', 'term'))));
+ },Registrar::withFeature('is_content', 'term'))));
if (!empty($isContent) && is_page($isContent)){
$type = get_post_meta(get_the_id(), BASE.'for_type', true);
diff --git a/inc/managers/SEO/render/Thing/Product/Product.php b/inc/managers/SEO/render/Thing/Product/Product.php
index b1ff016..b0c0a63 100644
--- a/inc/managers/SEO/render/Thing/Product/Product.php
+++ b/inc/managers/SEO/render/Thing/Product/Product.php
@@ -2,6 +2,7 @@
namespace JVBase\managers\SEO\render\Thing\Product;
+use JVBase\managers\SEO\render\Thing\Thing;
use JVBase\managers\SEO\render\Traits\_Properties\additionalPropertyTrait;
use JVBase\managers\SEO\render\Traits\_Properties\aggregateRatingTrait;
use JVBase\managers\SEO\render\Traits\_Properties\audienceTrait;
@@ -41,15 +42,13 @@
use JVBase\managers\SEO\render\Traits\_Properties\sloganTrait;
use JVBase\managers\SEO\render\Traits\_Properties\weightTrait;
use JVBase\managers\SEO\render\Traits\_Properties\widthTrait;
-use JVBase\managers\SEO\render\Traits\ThingSchema;
if (!defined('ABSPATH')) {
exit;
}
-class Product {
- use ThingSchema,
- additionalPropertyTrait, aggregateRatingTrait, audienceTrait,
+class Product extends Thing {
+ use additionalPropertyTrait, aggregateRatingTrait, audienceTrait,
awardTrait, brandTrait, categoryTrait, colorTrait, countryOfAssemblyTrait,
countryOfOriginTrait, depthTrait, displayLocationTrait, hasAdultConsiderationTrait,
hasCertificationTrait, hasMeasurementTrait, hasMerchantReturnPolicyTrait,
diff --git a/inc/managers/VerifyEntryManager.php b/inc/managers/VerifyEntryManager.php
index 69bfb01..01fb039 100644
--- a/inc/managers/VerifyEntryManager.php
+++ b/inc/managers/VerifyEntryManager.php
@@ -17,7 +17,7 @@
protected function defineTables():void
{
- $types = implode(',', array_map(function($item) { return "`{$item}`"; },Registrar::getFeatured('verify_entry')));
+ $types = implode(',', array_map(function($item) { return "`{$item}`"; },Registrar::withFeature('verify_entry')));
$table = CustomTable::for('verify_entry');
diff --git a/inc/managers/_setup.php b/inc/managers/_setup.php
index a2ca4ec..d55098a 100644
--- a/inc/managers/_setup.php
+++ b/inc/managers/_setup.php
@@ -49,7 +49,7 @@
require(JVB_DIR . '/inc/managers/UserTermsManager.php');
}
- if (!empty(Registrar::getFeatured('approve_new'))) {
+ if (!empty(Registrar::withFeature('approve_new'))) {
require(JVB_DIR . '/inc/managers/ApprovalManager.php');
}
@@ -63,7 +63,7 @@
require(JVB_DIR . '/inc/managers/Notifications/Preferences.php');
require(JVB_DIR . '/inc/managers/NotificationManager.php');
}
- if ($membership->has('forum') && !empty(Registrar::getFeatured('is_content', 'term'))) {
+ if ($membership->has('forum') && !empty(Registrar::withFeature('is_content', 'term'))) {
require(JVB_DIR . '/inc/managers/NewsRelationships.php');
}
if ($membership->has('invitable')) {
@@ -83,10 +83,10 @@
require(JVB_DIR . '/inc/managers/ReferralManager.php');
}
- if (!empty(Registrar::getFeatured('karma'))) {
+ if (!empty(Registrar::withFeature('karma'))) {
require(JVB_DIR . '/inc/managers/KarmaManager.php');
}
-// if (Site::has('favourites') && !empty(Registrar::getFeatured('favouritable'))) {
+// if (Site::has('favourites') && !empty(Registrar::withFeature('favouritable'))) {
if (Site::has('favourites')) {
require(JVB_DIR . '/inc/managers/FavouritesManager.php');
}
diff --git a/inc/registrar/Fields.php b/inc/registrar/Fields.php
index 522b5d1..5635c0c 100644
--- a/inc/registrar/Fields.php
+++ b/inc/registrar/Fields.php
@@ -17,7 +17,7 @@
class Fields {
protected array $fields;
- protected Registrar $registrar;
+ private Registrar $registrar;
public function __construct(?string $type = null, ?Registrar $registrar = null) {
$this->registrar = $registrar;
diff --git a/inc/registrar/Registrar.php b/inc/registrar/Registrar.php
index 19b92fd..6b5cf2c 100644
--- a/inc/registrar/Registrar.php
+++ b/inc/registrar/Registrar.php
@@ -468,7 +468,8 @@
{
return $this->integrationConfigs;
}
- public function hasIntegration(string $integration) {
+ public function hasIntegration(string $integration):bool
+ {
return array_key_exists($integration, $this->integrationConfigs);
}
public function hasAnyIntegrations(array $integrations = []):bool
@@ -562,6 +563,24 @@
}
return $this;
}
+ public function unsetAll(array $flags):self
+ {
+ $flags = array_filter($flags, function($flag) {
+ return in_array($flag, static::$allFlags);
+ });
+ foreach ($flags as $flag) {
+ $this->$flag = false;
+ switch ($flag) {
+ case 'is_content':
+ remove_action('init', [$this, 'setupContent'], 20);
+ break;
+ case 'is_glossary':
+ $this->hide_single = false;
+ break;
+ }
+ }
+ return $this;
+ }
public function prefixWith(string $prefix):self
{
$this->prefix_with = sanitize_title($prefix);
@@ -654,7 +673,7 @@
protected function getBreadcrumbs():Breadcrumbs
{
if (!isset($this->breadcrumbs)) {
- $this->breadcrumbs = new Breadcrumbs($this->slug, $this);
+ $this->breadcrumbs = new Breadcrumbs($this->slug);
}
return $this->breadcrumbs;
@@ -672,7 +691,7 @@
protected function getDashboard():Dashboard
{
if (!isset($this->dashboard)) {
- $this->dashboard = new Dashboard($this->plural, $this);
+ $this->dashboard = new Dashboard($this->plural);
}
return $this->dashboard;
@@ -715,11 +734,42 @@
}
public function addSection(string $title):Section
{
- $section = new Section($title, $this);
- $this->sections[] = $section;
- return $section;
+ $slug = sanitize_title($title);
+ if (!array_key_exists($slug, $this->sections)) {
+ $section = new Section($title, $this);
+ $this->sections[$slug] = $section;
+ }
+
+ return $this->sections[$slug];
}
+ public static function maybeBuildSections():void
+ {
+ foreach (self::$instances as $inst) {
+ $inst->buildSections();
+ }
+ }
+ protected function buildSections():void
+ {
+ $fields = $this->getFields();
+ $sections = array_unique(array_values(array_map(function ($f) {
+ return array_key_exists('section', $f) && !is_null($f['section']) ? $f['section'] : 'main';
+ }, $fields)));
+
+ foreach ($sections as $s) {
+ $section = new Section($s, $this);
+ $section->setTitle(ucwords(implode(' ', explode('-', $s))));
+ $sectionFields = array_map(function ($f) {
+ return $f['name'];
+ }, array_filter($fields, function ($f) use ($s) {
+ $tmp = array_key_exists('section', $f) && !is_null($f['section']) ? $f['section'] : 'main';
+ return $s === $tmp;
+ }));
+ $section->setFields($sectionFields);
+ $this->sections[$s] = $section;
+ }
+ }
+
public function setSectionOrder(array $sections):self
{
$allSections = array_map(function($section) {
@@ -767,7 +817,7 @@
$this->hideSingleHandler = new HideSingle($this->slug, $this);
}
if ($this->is_timeline) {
- $this->isTimelineHandler = new MakeTimelineType($this->slug, $this);
+ $this->isTimelineHandler = new MakeTimelineType($this->slug);
$this->registrar->hierarchical = true;
}
if ($this->is_calendar) {
@@ -1104,8 +1154,8 @@
public static function ensureInstanced():void
{
if (empty(self::$instances)) {
- do_action('jvbDefineRegistrar');
- do_action('jvbDefineRegistrarFields');
+ do_action('jvb_define_registrar');
+ do_action('jvb_define_fields');
}
}
diff --git a/inc/registrar/config/Integration.php b/inc/registrar/config/Integration.php
index a25324d..8a829d5 100644
--- a/inc/registrar/config/Integration.php
+++ b/inc/registrar/config/Integration.php
@@ -38,6 +38,7 @@
$this->service_name = $service;
}
+
public function getService_name():string
{
return $this->service_name;
@@ -49,7 +50,12 @@
*/
public function setContentType(string $content):self
{
- $allowed = JVB()->connect($this->service_name)->getAllowedContent();
+ $connection = JVB()->connect($this->service_name);
+ if (!$connection){
+ error_log('[Integration]::setContentType Service is not setup. '.$this->service_name);
+ return $this;
+ }
+ $allowed = $connection->getAllowedContent();
if (!in_array($content, $allowed)) {
error_log($this->service_name.' Connection does not support this content: '.$content);
return $this;
diff --git a/inc/registrar/config/Section.php b/inc/registrar/config/Section.php
index d5d6c51..10ac615 100644
--- a/inc/registrar/config/Section.php
+++ b/inc/registrar/config/Section.php
@@ -13,11 +13,10 @@
protected string $description = '';
protected string $icon = '';
protected array $fields = [];
- protected Registrar $registrar;
+ private Registrar $registrar;
- public function __construct(string $title, Registrar $registrar) {
- $this->title = $title;
- $this->slug = sanitize_title($title);
+ public function __construct(string $slug, Registrar $registrar) {
+ $this->slug = sanitize_title($slug);
$this->registrar = $registrar;
}
@@ -27,7 +26,7 @@
}
public function getTitle():string
{
- return $this->title;
+ return $this->title ?? ucwords(implode(' ', explode('-', $this->slug)));
}
public function setDescription(string $description):self
@@ -45,6 +44,10 @@
$this->icon = $icon;
return $this;
}
+ public function getIcon():string
+ {
+ return $this->icon;
+ }
protected function checkFields(string|array $fields):string|array
{
diff --git a/inc/registrar/fields/Field.php b/inc/registrar/fields/Field.php
index c1d5e33..f24de84 100644
--- a/inc/registrar/fields/Field.php
+++ b/inc/registrar/fields/Field.php
@@ -21,6 +21,10 @@
protected int $maxLength; // of characters
protected int $min;
protected int $max;
+ /**
+ * @var float $step For number fields. Indicates the amount the number increases/decreases with the plus/minus buttons
+ */
+ protected float $step;
protected string $subtype;
protected array $condition;
protected array $allowedSubtype = ['text', 'url','number','tel','email','number'];
@@ -64,6 +68,11 @@
}
}
+ public function getName():string
+ {
+ return $this->name;
+ }
+
public function setDescription(string $description):void
{
$this->description = $description;
@@ -144,6 +153,14 @@
{
return $this->max??null;
}
+ public function setStep(float $step):void
+ {
+ $this->step = $step;
+ }
+ public function getStep():?float
+ {
+ return $this->step??null;
+ }
public function setMaxLength(int $maxLength):void
{
$this->maxLength = $maxLength;
diff --git a/inc/registrar/helpers/AddIntegrationFields.php b/inc/registrar/helpers/AddIntegrationFields.php
index 29fe741..1f3fd11 100644
--- a/inc/registrar/helpers/AddIntegrationFields.php
+++ b/inc/registrar/helpers/AddIntegrationFields.php
@@ -11,13 +11,13 @@
class AddIntegrationFields {
protected string $service_name;
- protected Registrar $registrar;
+ private Registrar $registrar;
protected Integration $config;
protected array $allowed;
public function __construct(string $service_name, ?Registrar $registrar = null) {
$this->initAllowed();
- if (!in_array($service_name, $this->allowed)) {
+ if (!array_key_exists($service_name, $this->allowed)) {
return;
}
@@ -28,6 +28,7 @@
$this->config = $registrar->getIntegration($service_name);
+ add_action('jvb_define_integrations', [$this, 'addIntegrationFields'],20);
}
protected function initAllowed():void
{
@@ -56,6 +57,7 @@
public function addIntegrationFields():void
{
$fields = $this->getIntegrationFields();
+// error_log('[AddIntegrationFields] adding fields for '.$this->service_name.': '.print_r($fields, true));
foreach ($fields as $fieldName => $fieldConfig) {
$this->registrar->fields()->addField($fieldName, $fieldConfig);
}
diff --git a/inc/registrar/helpers/HideSingle.php b/inc/registrar/helpers/HideSingle.php
index 20ef320..9c00ca8 100644
--- a/inc/registrar/helpers/HideSingle.php
+++ b/inc/registrar/helpers/HideSingle.php
@@ -12,15 +12,14 @@
class HideSingle {
protected string $slug;
protected string $postType;
- protected Registrar $registrar;
public function __construct(string $slug, Registrar $registrar) {
$this->slug = $slug;
$this->postType = jvbCheckBase($slug);
- $this->registrar = $registrar;
- if ($this->registrar->hasFeature('hide_single')) {
+
+ if ($registrar->hasFeature('hide_single')) {
add_filter('is_post_type_viewable', [$this, 'hideFromPublic']);
- if ($this->registrar->hasFeature('redirect_to_author')) {
+ if ($registrar->hasFeature('redirect_to_author')) {
add_filter('post_type_link', [$this, 'redirectSingleToAuthor'], 15, 2);
add_action('template_redirect', [$this, 'actuallyRedirectToAuthor']);
} else {
diff --git a/inc/registrar/helpers/MakeCalendarType.php b/inc/registrar/helpers/MakeCalendarType.php
index 9ad4d76..be83235 100644
--- a/inc/registrar/helpers/MakeCalendarType.php
+++ b/inc/registrar/helpers/MakeCalendarType.php
@@ -12,7 +12,7 @@
class MakeCalendarType {
protected string $slug;
protected string $postType;
- protected Registrar $registrar;
+ private Registrar $registrar;
public function __construct(string $slug, Registrar $registrar) {
$this->slug = $slug;
$this->postType = jvbCheckBase($slug);
@@ -25,6 +25,13 @@
add_action('init', [$this, 'addCalendarRewrites']);
}
+
+ public function __debugInfo() {
+ $vars = get_object_vars($this);
+ unset($vars['registrar']);
+ return $vars;
+ }
+
protected function addCalendarFields():void
{
diff --git a/inc/registrar/helpers/MakeTimelineType.php b/inc/registrar/helpers/MakeTimelineType.php
index 84ea959..f8e2e49 100644
--- a/inc/registrar/helpers/MakeTimelineType.php
+++ b/inc/registrar/helpers/MakeTimelineType.php
@@ -12,11 +12,9 @@
class MakeTimelineType {
protected string $slug;
protected string $postType;
- protected Registrar $registrar;
- public function __construct(string $slug, Registrar $registrar) {
+ public function __construct(string $slug) {
$this->slug = $slug;
$this->postType = jvbCheckBase($slug);
- $this->registrar = $registrar;
add_action('template_redirect', [$this, 'redirectChildToParent']);
}
diff --git a/inc/rest/Rest.php b/inc/rest/Rest.php
index dd6c9cb..557929d 100644
--- a/inc/rest/Rest.php
+++ b/inc/rest/Rest.php
@@ -224,7 +224,7 @@
// Keep existing author filtering logic
$authorQuery = [];
- foreach (Registrar::getFeatured('can_create', 'user') as $type) {
+ foreach (Registrar::withFeature('can_create', 'user') as $type) {
if (array_key_exists($type, $data)) {
$artist_ids = array_map(
'absint',
@@ -537,7 +537,7 @@
return false;
}
$post_types = is_array($args['post_type']) ? $args['post_type'] : [$args['post_type']];
- $hasTimeline = array_map(function($item) { return jvbCheckBase($item); },Registrar::getFeatured('is_timeline', 'post'));
+ $hasTimeline = array_map(function($item) { return jvbCheckBase($item); },Registrar::withFeature('is_timeline', 'post'));
return !empty(array_intersect($post_types, $hasTimeline));
}
// =========================================================================
diff --git a/inc/rest/RestRouteManager.php b/inc/rest/RestRouteManager.php
index ff72f13..91778c7 100644
--- a/inc/rest/RestRouteManager.php
+++ b/inc/rest/RestRouteManager.php
@@ -323,7 +323,7 @@
// Keep existing author filtering logic
$authorQuery = [];
- foreach (Registrar::getFeatured('can_create', 'user') as $type) {
+ foreach (Registrar::withFeature('can_create', 'user') as $type) {
if (array_key_exists($type, $data)) {
$artist_ids = array_map(
'absint',
@@ -479,7 +479,7 @@
protected function isTimeline($args, $data):bool
{
$post_types = is_array($args['post_type']) ? $args['post_type'] : [$args['post_type']];
- $areTimeline = array_map(function($type) { return BASE.$type; },Registrar::getFeatured('is_timeline', 'post'));
+ $areTimeline = array_map(function($type) { return BASE.$type; },Registrar::withFeature('is_timeline', 'post'));
return !empty(array_intersect($post_types, $areTimeline));
}
diff --git a/inc/rest/_setup.php b/inc/rest/_setup.php
index 89dcf34..f1e28bb 100644
--- a/inc/rest/_setup.php
+++ b/inc/rest/_setup.php
@@ -51,11 +51,11 @@
//if (Site::has('referrals')) {
require(JVB_DIR . '/inc/rest/routes/ReferralRoutes.php');
//}
-//if (!empty(Registrar::getFeatured('has_responses'))) {
+//if (!empty(Registrar::withFeature('has_responses'))) {
require(JVB_DIR . '/inc/rest/routes/ResponseRoutes.php');
//}
-//if (!empty(Registrar::getFeatured('karma'))) {
+//if (!empty(Registrar::withFeature('karma'))) {
require(JVB_DIR . '/inc/rest/routes/VoteRoutes.php');
//}
diff --git a/inc/rest/routes/ApprovalRoutes.php b/inc/rest/routes/ApprovalRoutes.php
index a051459..b35e485 100644
--- a/inc/rest/routes/ApprovalRoutes.php
+++ b/inc/rest/routes/ApprovalRoutes.php
@@ -41,11 +41,11 @@
$this->termTypes = [];
$this->allTypes = [];
if ($this->hasMemberApproval) {
- $this->userTypes = Registrar::getFeatured('approve_new', 'user');
+ $this->userTypes = Registrar::withFeature('approve_new', 'user');
$this->allTypes = $this->userTypes;
}
if (Site::has('term_approval')) {
- $this->termTypes = Registrar::getFeatured('approve_new', 'term');
+ $this->termTypes = Registrar::withFeature('approve_new', 'term');
$this->allTypes[] = 'term';
}
}
diff --git a/inc/rest/routes/ContentTermsRoutes.php b/inc/rest/routes/ContentTermsRoutes.php
index ce50632..37c9d03 100644
--- a/inc/rest/routes/ContentTermsRoutes.php
+++ b/inc/rest/routes/ContentTermsRoutes.php
@@ -55,7 +55,7 @@
{
$registry = JVB()->queue()->registry();
$executor = new ContentTermExecutor();
- $taxonomies = Registrar::getFeatured('is_content', 'term');
+ $taxonomies = Registrar::withFeature('is_content', 'term');
foreach($taxonomies as $taxonomy) {
$registry->register("{$taxonomy}_update", new TypeConfig(
diff --git a/inc/rest/routes/FeedRoutes.php b/inc/rest/routes/FeedRoutes.php
index 6abb894..f4e0ab1 100644
--- a/inc/rest/routes/FeedRoutes.php
+++ b/inc/rest/routes/FeedRoutes.php
@@ -501,7 +501,7 @@
: explode(',', $args['post_type']);
// Check if filtering global feed content
- if (in_array(jvbNoBase($context['type']), Registrar::getFeatured('is_content', 'term'))) {
+ if (in_array(jvbNoBase($context['type']), Registrar::withFeature('is_content', 'term'))) {
// Global: show posts from any content type with this taxonomy
$for_content = Registrar::getInstance($context['type'])->registrar->for ?? [];
@@ -509,7 +509,7 @@
$post_types = array_map(fn($type) => jvbCheckBase($type), $for_content);
// Filter to only show_feed content types
- $show_feed_types = Registrar::getFeatured('show_feed', 'post');
+ $show_feed_types = Registrar::withFeature('show_feed', 'post');
$args['post_type'] = array_intersect(
$post_types,
array_map(fn($type) => jvbCheckBase($type), $show_feed_types)
@@ -1147,7 +1147,7 @@
$config = [];
// Get content types with show_feed
- $contentTypes = Registrar::getFeatured('show_feed', 'post');
+ $contentTypes = Registrar::withFeature('show_feed', 'post');
foreach ($contentTypes as $slug) {
$this->cache->tag('content:'.$slug);
$registrar = Registrar::getInstance($slug);
@@ -1163,7 +1163,7 @@
}
// Get taxonomies with show_feed (content taxonomies)
- $taxonomies = Registrar::getFeatured('show_feed', 'term');
+ $taxonomies = Registrar::withFeature('show_feed', 'term');
foreach ($taxonomies as $slug) {
$registrar = Registrar::getInstance($slug);
if (!$registrar || !($registrar->hasFeature('is_content') ?? false)) {
diff --git a/inc/rest/routes/LoginRoutes.php b/inc/rest/routes/LoginRoutes.php
index 2e863ee..b4563aa 100644
--- a/inc/rest/routes/LoginRoutes.php
+++ b/inc/rest/routes/LoginRoutes.php
@@ -136,18 +136,23 @@
*/
public function handleLogin(WP_REST_Request $request): WP_REST_Response
{
+ error_log('Handling login...');
$email = sanitize_email($request->get_param('user_email'));
$password = $request->get_param('user_password');
$remember = (bool) $request->get_param('remember_me');
$redirect_to = $request->get_param('redirect_to');
// Verify Turnstile
+
if (!$this->verifyTurnstile($request->get_param('cf-turnstile-response') ?? '')) {
+ error_log('[handleLogin]Turnstile failed');
return $this->error(
'Security verification failed. Please try again.',
'turnstile_failed',
403
);
+ } else {
+ error_log('[handleLogin]Turnstile succeeded');
}
// Attempt authentication
@@ -720,22 +725,20 @@
protected function buildAuth(?int $user = null): array
{
$userId = $user ?? (is_user_logged_in() ? get_current_user_id() : 0);
- $cacheKey = $userId ?: 'guest';
- return Cache::for('auth', 300)->remember($cacheKey, function() use ($userId) {
- if ($userId) {
- return [
- 'authenticated' => true,
- 'user' => $userId,
- 'nonces' => $this->getUserNonces($userId),
- ];
- }
+ if ($userId) {
return [
- 'authenticated' => false,
- 'user' => false,
- 'nonces' => ['wp_rest' => wp_create_nonce('wp_rest')],
+ 'authenticated' => true,
+ 'user' => $userId,
+ 'nonces' => $this->getUserNonces($userId),
];
- });
+ }
+
+ return [
+ 'authenticated' => false,
+ 'user' => false,
+ 'nonces' => ['wp_rest' => wp_create_nonce('wp_rest')],
+ ];
}
protected function getUserNonces(int $userID):array {
$nonces = [
@@ -747,7 +750,7 @@
if (Site::has('favourites')) {
$nonces['favourites'] = wp_create_nonce('favourites-'.$userID);
}
- if (!empty(Registrar::getFeatured('karma'))) {
+ if (!empty(Registrar::withFeature('karma'))) {
$nonces['votes'] = wp_create_nonce('votes-'.$userID);
}
if (Site::has('notifications')) {
diff --git a/inc/rest/routes/NotificationsRoutes.php b/inc/rest/routes/NotificationsRoutes.php
index ff84cdc..eaf3e7f 100644
--- a/inc/rest/routes/NotificationsRoutes.php
+++ b/inc/rest/routes/NotificationsRoutes.php
@@ -555,7 +555,7 @@
$statusCondition = $wpdb->prepare("a.status = %s", $status);
}
- $approvals = Registrar::getFeatured('approve_new');
+ $approvals = Registrar::withFeature('approve_new');
foreach ($approvals as $type => $config) {
$table = $wpdb->prefix . BASE . 'approval_' . $type . 'requests';
$votes = $wpdb->prefix . BASE . 'approval_' . $type . 'votes';
diff --git a/jvb.php b/jvb.php
index 3987ea3..16816ed 100644
--- a/jvb.php
+++ b/jvb.php
@@ -4,7 +4,7 @@
Plugin URI: https://jakevan.ca
Description: The Base Plugin for JakeVan clients
Author: Jake Vanderwerf
-Version: 1.0.0
+Version: 1.1.0
Author URI: https://jakevan.ca/
Textdomain: jvb
*/
@@ -88,6 +88,7 @@
}, 10, 3);
+
function jvbIgnoredPostTypes():array
{
return [BASE.'directory', BASE.'dash', 'attachment', 'revision', 'nav_menu_item'];
@@ -248,11 +249,54 @@
require(JVB_DIR . '/inc/admin/_setup.php');
require(JVB_DIR . '/JVBase.php');
+
+/**
+ * After moving to the Registrar::based registration, we need to carefully time
+ * when Site gets defined, as well as Registrar initial definitions, field definitions,
+ * and integration config
+ * These custom actions should simplify the timing for us.
+ */
+add_action('plugins_loaded', 'jvb_site_definitions',1);
+add_action('plugins_loaded', 'jvb_registrar_definitions',2);
+add_action('plugins_loaded', 'jvb_field_definitions', 3);
add_action('init', 'jvbLoadBase', 1);
+add_action('init', 'jvb_integration_definitions',3);
+add_action('init', 'jvb_field_section_definitions', 5);
+/**
+ * Can define the Site settings
+ * @return void
+ */
+function jvb_site_definitions():void
+{
+ do_action('jvb_define_site');
+}
+function jvb_registrar_definitions():void
+{
+ do_action('jvb_define_registrar');
+}
+function jvb_field_definitions():void
+{
+ do_action('jvb_define_fields');
+}
+
+
function jvbLoadBase():void
{
JVB::getInstance();
}
+
+function jvb_integration_definitions():void
+{
+ do_action('jvb_define_integrations');
+}
+
+function jvb_field_section_definitions():void
+{
+ do_action('jvb_define_field_sections');
+ Registrar::maybeBuildSections();
+}
+
+
function JVB(): JVB
{
return JVB::getInstance();
@@ -317,7 +361,7 @@
if (Site::has('favourites')) {
$interactions[] = 'favourites';
}
- if (!empty(Registrar::getFeatured('karma'))) {
+ if (!empty(Registrar::withFeature('karma'))) {
$interactions[] = 'karma';
}
if (Site::has('notifications')) {
@@ -372,7 +416,7 @@
}';
}
- if (!empty(Registrar::getFeatured('karma'))) {
+ if (!empty(Registrar::withFeature('karma'))) {
wp_enqueue_script('jvb-votes');
$initUserSettings .= '// Fetch user votes
try {
--
Gitblit v1.10.0