| | |
| | | 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')) { |
| | |
| | | protected array $filters; |
| | | protected array $bulkActions; |
| | | protected MetaManager $meta; |
| | | protected MetaForm $form; |
| | | protected array $taxonomies; |
| | | protected array $statuses; |
| | | protected array $fields; |
| | |
| | | ]; |
| | | |
| | | $this->init(); |
| | | add_filter('jvbAdditionalActions', [$this, 'createItem']); |
| | | } |
| | | |
| | | protected function init():void |
| | |
| | | $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; |
| | |
| | | '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> |
| | |
| | | $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 |
| | |
| | | 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() ?> |
| | |
| | | |
| | | protected function renderModals():void |
| | | { |
| | | $this->renderCreateModal(); |
| | | // $this->renderCreateModal(); |
| | | $this->renderEditModal(); |
| | | $this->renderBulkEditModal(); |
| | | } |
| | |
| | | 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"> |
| | |
| | | } 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'; |
| | |
| | | } else { |
| | | $this->meta->render('form', $n, $config); |
| | | } |
| | | |
| | | } |
| | | |
| | | |
| | | if ($tabs) { |
| | | jvbRenderTabs($tabs); |
| | | } |
| | |
| | | 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') { |
| | |
| | | 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> |
| | |
| | | $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(); |
| | | |
| | |
| | | data-save="content" |
| | | data-content="<?= esc_attr($this->content) ?>" |
| | | data-form-id="content-table-<?= esc_attr($this->content) ?>"> |
| | | |
| | | <?= jvbFormStatus() ?> |
| | | <?= $this->renderTableActions() ?> |
| | | |
| | | <table> |
| | |
| | | <?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; |
| | | } |
| | | } |