From 42fa8304ddb811b0f725f245130f70c0f5e86a6c Mon Sep 17 00:00:00 2001
From: Jake Vanderwerf <get@jakevanderwerf.ca>
Date: Tue, 04 Nov 2025 06:12:02 +0000
Subject: [PATCH] =Refactored LoginManager to be more extensible and configurable, as well as an AjaxRateLimiter
---
inc/managers/CRUDManager.php | 157 ++++++++++++++++++++++++++++++++++++++++++++++------
1 files changed, 138 insertions(+), 19 deletions(-)
diff --git a/inc/managers/CRUDManager.php b/inc/managers/CRUDManager.php
index 6deb11e..37b3a59 100644
--- a/inc/managers/CRUDManager.php
+++ b/inc/managers/CRUDManager.php
@@ -2,7 +2,9 @@
namespace JVBase\managers;
use JVBase\managers\UserTermsManager;
+use JVBase\meta\MetaForm;
use JVBase\meta\MetaManager;
+use JVBase\utility\Features;
use WP_User;
if (!defined('ABSPATH')) {
@@ -19,6 +21,7 @@
protected array $filters;
protected array $bulkActions;
protected MetaManager $meta;
+ protected MetaForm $form;
protected array $taxonomies;
protected array $statuses;
protected array $fields;
@@ -47,6 +50,7 @@
];
$this->init();
+ add_filter('jvbAdditionalActions', [$this, 'createItem']);
}
protected function init():void
@@ -56,7 +60,7 @@
$this->initTaxonomies();
$this->initFilters();
$this->meta = new MetaManager(null, 'post', $this->content);
-
+ $this->form = new MetaForm();
$plural = strtolower($this->config['plural']??$this->content.'s');
$this->userCanPublish = (jvbUserIsVerified()) ?
user_can($this->user_id, "publish_{$plural}") : false;
@@ -192,13 +196,13 @@
'multiple' => true,
'destination' => 'post'
];
- if (!jvbCheck('single_image', $this->config)) {
+ if (!array_key_exists('single_image', $this->config) || $this->config['single_image'] === false) {
$uploadConfig['destination'] = 'post_group';
}
$uploadConfig['destination'] = 'post_group';
if (!jvbCheck('single_image', $this->config)) {
- $uploadConfig['group_title'] = 'Create '.$this->config['plural'];
- $uploadConfig['group_description'] = '<p>Drag images into groups. Each group becomes its own '.$this->singular.'.</p>
+ $uploadConfig['label'] = 'Create '.$this->config['plural'];
+ $uploadConfig['upload_text'] = '<p>Drag images into groups. Each group becomes its own '.$this->singular.'.</p>
<p>You can also select multiple images and click the "Add to Group" button.</p>
<p>If a '.$this->singular.' has multiple images, you can select the '.jvbIcon('star').' to set an image as the main one.</p>
<p>Images left ungrouped will become individual '.$this->plural.'</p>
@@ -207,7 +211,6 @@
$uploadConfig['description'] = 'Each image will become its own '.$this->singular.'.';
}
?>
- <button type="button" class="create-item row" title="Create New <?= $this->singular?>"><?=jvbIcon('add') ?><span class="screen-reader-text">Create New <?= $this->singular?></span></button>
<details open class="uploader">
<summary class="row btw"><?= $this->config['upload_title'] ?? 'Bulk Upload '.$this->plural?></summary>
<?php
@@ -256,7 +259,7 @@
protected function renderFilters():void
{
?>
- <div class="all-filters col start">
+ <div class="all-filters col start" data-ignore>
<div class="search row start nowrap">
<span class="label">Search:</span>
<?= jvbSearch() ?>
@@ -585,7 +588,7 @@
protected function renderModals():void
{
- $this->renderCreateModal();
+// $this->renderCreateModal();
$this->renderEditModal();
$this->renderBulkEditModal();
}
@@ -603,6 +606,7 @@
ob_start();
?>
<form class="edit-form" data-save="content" data-form-id="edit-<?=$this->content?>">
+ <?= jvbFormStatus() ?>
<input type="hidden" name="form-id" value="<?=uniqid('new-')?>" />
<input type="hidden" name="content" value="<?=$this->content?>" />
<div class="fields">
@@ -632,20 +636,59 @@
} else {
$tabs = false;
}
+
+ $isTimeline = Features::forContent($this->content)->has('is_timeline');
+
+
$fields = $this->fields;
+ if (!$isTimeline) {
+ $first = ['post_thumbnail', 'post_title', 'price'];
- $first = ['post_thumbnail', 'post_title', 'price'];
- foreach ($first as $f) {
- if (array_key_exists($f, $fields)) {
- if ($tabs) {
- $tabs['basic']['content'] .= $this->meta->render('form', $f, $fields[$f], false, true);
- } else {
- $this->meta->render('form', $f, $fields[$f]);
+ foreach ($first as $f) {
+ if (array_key_exists($f, $fields)) {
+ if ($tabs) {
+ $tabs['basic']['content'] .= $this->meta->render('form', $f, $fields[$f], false, true);
+ } else {
+ $this->meta->render('form', $f, $fields[$f]);
+ }
+
+ unset($fields[$f]);
}
-
- unset($fields[$f]);
}
}
+
+ if ($isTimeline) {
+ $temp = array_filter($fields, function ($field) {
+ if (array_key_exists('for_all', $field) && $field['for_all'] === true) {
+ return true;
+ }
+ return false;
+ });
+ $config = [
+ 'type' => 'gallery',
+ 'subtype' => 'timeline',
+ 'data' => 'timeline',
+ 'label' => 'Progression',
+ 'fields' => $temp
+ ];
+ $content = '';
+ foreach ($fields as $slug=> $field) {
+ if (!array_key_exists('for_all', $field) || $field['for_all'] === false) {
+ $content .= $this->form->render($slug, null, $field, false, true);
+ }
+ }
+
+ $content .= $this->meta->render('form', 'timeline', $config, false,true);
+
+ $tabs['progression']['content'] = $content;
+ $this->fields = array_filter($fields, function ($field) {
+ if (array_key_exists('for_all', $field) && $field['for_all'] === true) {
+ return false;
+ }
+ return true;
+ });
+ $fields = $this->fields;
+ }
foreach ($fields as $n => $config) {
if ($tabs) {
$section = (array_key_exists('section', $config)) ? $config['section'] : 'basic';
@@ -653,10 +696,8 @@
} else {
$this->meta->render('form', $n, $config);
}
-
}
-
if ($tabs) {
jvbRenderTabs($tabs);
}
@@ -667,6 +708,58 @@
return ob_get_clean();
}
+
+ protected function renderTimelineFields():string
+ {
+ ob_start();
+
+
+ ?>
+ <div class="repeater-field timeline-repeater" data-timeline data-field="fields">
+ <div class="repeater-rows" data-repeater-container>
+ <!-- Parent row (non-draggable) -->
+ <div class="repeater-row parent-row" data-row-index="0" data-id="">
+ <div class="row-header">
+ <h4>Before (Starting Point)</h4>
+ </div>
+ <div class="row-fields">
+ <?php $this->renderRowFields(); ?>
+ </div>
+ </div>
+
+ <!-- Child rows will be added dynamically -->
+ </div>
+
+ <button type="button" class="add-repeater-row btn secondary">
+ <?= jvbIcon('add') ?>
+ <span>Add Progress Step</span>
+ </button>
+ </div>
+ <?php
+ return ob_get_clean();
+ }
+
+ protected function renderRowFields():void
+ {
+ $fields = $this->fields;
+
+ // Render priority fields first
+ $first = ['post_thumbnail', 'post_title', 'price'];
+ foreach ($first as $f) {
+ if (array_key_exists($f, $fields)) {
+ $this->meta->render('form', $f, $fields[$f]);
+ unset($fields[$f]);
+ }
+ }
+
+ // Render remaining fields
+ foreach ($fields as $name => $config) {
+ if (!array_key_exists('hidden', $config) || !$config['hidden']) {
+ $this->meta->render('form', $name, $config);
+ }
+ }
+ }
+
protected function getApplicableStatuses(string $prefix) {
foreach ($this->statuses as $status => $config) {
if ($status === 'all') {
@@ -713,6 +806,7 @@
ob_start();
?>
<form class="bulk-edit-form" data-save="content" data-form-id="bulk-edit-<?=$this->content?>">
+ <?= jvbFormStatus() ?>
<div class="selected"></div>
<p class="description">You can unselect items by clicking the image here.</p>
<p class="hint"><strong>IMPORTANT: </strong> Whatever changes you make here will be applied to all selected <?=$this->plural?>.</p>
@@ -776,6 +870,18 @@
$this->renderGridView();
$this->renderTableView();
$this->renderTableRow();
+ if (Features::forContent($this->content)->has('is_timeline')) {
+ $temp = array_filter($this->fields, function ($field) {
+ if (array_key_exists('for_all', $field) && $field['for_all'] === true) {
+ return true;
+ }
+ return false;
+ });
+ $form = new MetaForm();
+ echo '<template class="uploadTimeline">';
+ $form->renderImagePreview(null,$temp);
+ echo '</template>';
+ }
echo jvbGetEmptyStateTemplate();
echo jvbGetGalleryPreviewTemplate();
@@ -886,7 +992,7 @@
data-save="content"
data-content="<?= esc_attr($this->content) ?>"
data-form-id="content-table-<?= esc_attr($this->content) ?>">
-
+ <?= jvbFormStatus() ?>
<?= $this->renderTableActions() ?>
<table>
@@ -1024,4 +1130,17 @@
<?php
return ob_get_clean();
}
+
+ public function createItem(array $actions):array
+ {
+ ob_start();
+ $this->renderCreateModal();
+ $content = ob_get_clean();
+ $create = [
+ 'button' => '<button type="button" class="create-item row" title="Create New '.$this->singular.'">'.jvbIcon('add').'<span class="screen-reader-text">Create New '.$this->singular.'</span></button>',
+ 'content' => $content,
+ ];
+ $actions[] = $create;
+ return $actions;
+ }
}
--
Gitblit v1.10.0