| | |
| | | <?php |
| | | namespace JVBase\ui; |
| | | |
| | | use JVBase\base\Site; |
| | | use JVBase\managers\UserTermsManager; |
| | | use JVBase\meta\MetaForm; |
| | | use JVBase\meta\MetaManager; |
| | | use JVBase\meta\Form; |
| | | use JVBase\registrar\Registrar; |
| | | use WP_User; |
| | | |
| | | if (!defined('ABSPATH')) { |
| | |
| | | protected string $dataType = ''; |
| | | protected string $singular = ''; |
| | | protected string $plural = ''; |
| | | protected string $icon = 'triangle'; |
| | | protected string $icon; |
| | | |
| | | // Capabilities |
| | | protected array $caps = []; |
| | |
| | | protected ?array $uploaderConfig = null; |
| | | |
| | | // Data |
| | | protected $dataSourceCallback = null; |
| | | protected array $templates = []; |
| | | |
| | | // Metadata handling |
| | | protected ?MetaManager $meta = null; |
| | | protected ?MetaForm $form = null; |
| | | |
| | | // UI Options |
| | | protected array $stuck = []; // Fields that stick when scrolling |
| | | protected bool $showHeader = true; |
| | |
| | | protected array $customDateRanges = []; |
| | | protected array $additionalClasses = []; |
| | | |
| | | protected ?Registrar $registrar; |
| | | public function __construct() { |
| | | $this->icon = jvbDefaultIcon(); |
| | | $this->user = wp_get_current_user(); |
| | | $this->user_id = $this->user->ID; |
| | | } |
| | |
| | | */ |
| | | public function content(string $type, string $singular, string $plural): self { |
| | | $this->dataType = $type; |
| | | $registrar = Registrar::getInstance($type); |
| | | if ($registrar) { |
| | | $this->registrar = Registrar::getInstance($type)??null; |
| | | $this->sections = $this->registrar->getSections(); |
| | | } |
| | | |
| | | $this->singular = $singular; |
| | | $this->plural = $plural; |
| | | return $this; |
| | |
| | | */ |
| | | public function addTaxonomyFilter(array $taxonomies, ?string $limit = null): self { |
| | | foreach($taxonomies as $taxonomy) { |
| | | $this->taxonomies[$taxonomy] = [ |
| | | 'type' => 'taxonomy', |
| | | 'taxonomy'=> $taxonomy, |
| | | 'limit' => $limit, |
| | | 'label' => JVB_TAXONOMY[$taxonomy]['plural']??'', |
| | | 'icon' => JVB_TAXONOMY[$taxonomy]['icon']??'' |
| | | ]; |
| | | $registrar = Registrar::getInstance($taxonomy); |
| | | |
| | | if ($registrar) { |
| | | $this->taxonomies[$taxonomy] = [ |
| | | 'type' => 'taxonomy', |
| | | 'taxonomy'=> $taxonomy, |
| | | 'limit' => $limit, |
| | | 'label' => $registrar->getPlural(), |
| | | 'icon' => $registrar->getIcon() |
| | | ]; |
| | | } |
| | | } |
| | | |
| | | return $this; |
| | | } |
| | | |
| | | protected function taxConfig(string $taxonomy, string $label = ''):array |
| | | { |
| | | $isVerified = $this->userIsVerified(); |
| | | $label = ($label === '') ? Registrar::getInstance($taxonomy)->getPlural() : $label; |
| | | return [ |
| | | 'type' => 'taxonomy', |
| | | 'label' => $label, |
| | | 'taxonomy' => $taxonomy, |
| | | 'createNew' => $isVerified, |
| | | 'multiple' => true, |
| | | 'mode' => 'append', |
| | | ]; |
| | | } |
| | | |
| | | protected function userIsVerified():bool |
| | | { |
| | | $membership = Site::membership(); |
| | | |
| | | return !($membership && $membership->has('member_verified')) || current_user_can('skip_moderation'); |
| | | } |
| | | |
| | | public function addSearch():self |
| | | { |
| | | $this->hasSearch = true; |
| | |
| | | } |
| | | |
| | | $this->timelineSharedFields = array_keys(array_filter($this->fields, function ($field) { |
| | | if (!array_key_exists('for_all', $field) || $field['for_all'] === false){ |
| | | if (!array_key_exists('for_all', $field) || $field['for_all'] === false || is_null($field['for_all'])){ |
| | | return true; |
| | | } |
| | | return false; |
| | | })); |
| | | array_unshift($this->timelineSharedFields, 'post_thumbnail'); |
| | | array_unshift($this->timelineSharedFields, 'post_title'); |
| | | array_unshift($this->timelineSharedFields, 'post_status'); |
| | | |
| | | $this->timelineUniqueFields = array_keys(array_filter($this->fields, function ($field) { |
| | | if (array_key_exists('for_all', $field) && $field['for_all'] === true) { |
| | |
| | | } |
| | | |
| | | /** |
| | | * Set the data source callback |
| | | * Callback should accept filters and return array of items |
| | | */ |
| | | public function dataSource(callable $callback): self { |
| | | $this->dataSourceCallback = $callback; |
| | | return $this; |
| | | } |
| | | |
| | | /** |
| | | * Add a custom template |
| | | */ |
| | | public function addTemplate(string $name, string $template): self { |
| | |
| | | return $this; |
| | | } |
| | | |
| | | /** |
| | | * Initialize meta handling |
| | | */ |
| | | public function initMeta(string $objectType = 'post', ?string $content = null): self { |
| | | $this->meta = new MetaManager(null, $objectType, $content ?? $this->dataType); |
| | | $this->form = new MetaForm(); |
| | | return $this; |
| | | } |
| | | |
| | | /** |
| | | * Build the configuration array |
| | |
| | | $config = $this->build(); |
| | | $classes = array_merge(['dashboard-page', $this->dataType], $this->additionalClasses); |
| | | |
| | | ob_start(); |
| | | // ob_start(); |
| | | ?> |
| | | <div class="<?= esc_attr(implode(' ', $classes)) ?>" data-type="<?= esc_attr($this->dataType) ?>"> |
| | | <?php |
| | |
| | | ?> |
| | | </div> |
| | | <?php |
| | | echo ob_get_clean(); |
| | | // echo ob_get_clean(); |
| | | } |
| | | |
| | | /** |
| | |
| | | * Render uploader section |
| | | */ |
| | | protected function renderUploader(): void { |
| | | if (!$this->meta) { |
| | | return; |
| | | } |
| | | ?> |
| | | <details open class="uploader"> |
| | | <summary class="row btw"><?= esc_html($this->uploaderConfig['label'] ?? 'Upload Files') ?></summary> |
| | | <?php |
| | | $this->meta->render( |
| | | 'form', |
| | | 'new_' . $this->dataType, |
| | | $this->uploaderConfig |
| | | ); |
| | | ?> |
| | | <summary class="row x-btw"><?= esc_html($this->uploaderConfig['label'] ?? 'Upload Files') ?></summary> |
| | | <form id="uploader" data-form-id="upload_new_<?=$this->dataType ?>"> |
| | | <?php |
| | | echo jvbFormRestore(); |
| | | echo Form::render( |
| | | 'new_' . $this->dataType, |
| | | '', |
| | | $this->uploaderConfig |
| | | ); |
| | | ?> |
| | | </form> |
| | | </details> |
| | | <?php |
| | | } |
| | |
| | | protected function renderContent(): void { |
| | | $dataIgnore = $this->useCRUDjs ? '' : ' data-ignore'; |
| | | ?> |
| | | <section class="items-list <?= esc_attr($this->dataType) ?> crud" data-content="<?= esc_attr($this->dataType) ?>" data-view="<?= $this->defaultView?>"<?=$dataIgnore?>> |
| | | <?php |
| | | $this->renderControlsAndFilters(); |
| | | <section class="items-list <?= esc_attr($this->dataType) ?> crud" data-content="<?= esc_attr($this->dataType) ?>" data-singular="<?=$this->singular?>" data-plural="<?=$this->plural?>" data-view="<?= $this->defaultView?>"<?=$dataIgnore?>> |
| | | <div class="wrap"> |
| | | <?php |
| | | $this->renderControlsAndFilters(); |
| | | |
| | | if ($this->showBulkControls) { |
| | | $this->renderBulkActions(); |
| | | } |
| | | ?> |
| | | if ($this->showBulkControls) { |
| | | $this->renderBulkActions(); |
| | | } |
| | | ?> |
| | | |
| | | <div class="<?= esc_attr($this->dataType) ?> item-grid" role="grid"></div> |
| | | <div class="scroll-sentinel" aria-hidden="true"></div> |
| | | <div class="<?= esc_attr($this->dataType) ?> item-grid" role="grid"></div> |
| | | <div class="scroll-sentinel" aria-hidden="true"></div> |
| | | </div> |
| | | </section> |
| | | <?php |
| | | } |
| | |
| | | return; |
| | | } |
| | | ?> |
| | | <details class="all-filters col start" data-ignore> |
| | | <details class="all-filters col top" data-ignore> |
| | | <summary>Filters</summary> |
| | | <?php |
| | | |
| | |
| | | $this->renderColumnSelector(); |
| | | } |
| | | ?> |
| | | <button data-action="refresh" data-ignore><?=jvbIcon('arrows-clockwise')?><span>Hard Refresh</span></span></button> |
| | | </details> |
| | | <button hidden data-action="clear-filters" data-ignore hidden><?=jvbIcon('x')?><span>Clear Filters</span></span></button> |
| | | <?php |
| | | } |
| | | |
| | |
| | | return; |
| | | } |
| | | ?> |
| | | <div class="search row start nowrap"> |
| | | <div class="search row left nowrap"> |
| | | <span class="label">Search:</span> |
| | | <?= jvbSearch() ?> |
| | | </div> |
| | |
| | | return; |
| | | } |
| | | ?> |
| | | <div class="radio-options view row"> |
| | | <div class="radio-options view row left"> |
| | | <span class="label">View:</span> |
| | | <?php |
| | | $views = [ |
| | |
| | | <label for="view-<?=$view?>" |
| | | title="<?=$views[$view]['label']?>"> |
| | | <?= jvbDashIcon($views[$view]['icon']) ?> |
| | | <span class="screen-reader-text"><?=$views[$view]['label']?></span> |
| | | <span class="label"><?=$views[$view]['label']?></span> |
| | | </label> |
| | | <?php |
| | | } |
| | |
| | | return; |
| | | } |
| | | ?> |
| | | <div class="radio-options status row"> |
| | | <div class="radio-options status row left"> |
| | | <span class="label">Status:</span> |
| | | <?php |
| | | $i = 1; |
| | |
| | | <input type="radio" class="btn" data-filter="status" value="<?=$status?>" name="status" id="<?=$status?>"<?=$checked?>> |
| | | <label for="<?=$status?>" title="<?=$config['label']?>"> |
| | | <?= jvbDashIcon($config['icon']) ?> |
| | | <span class="label"><?= $config['label'] ?></span> |
| | | </label> |
| | | <?php |
| | | $i++; |
| | |
| | | protected function renderOrderControls():void |
| | | { |
| | | ?> |
| | | <div class="radio-options order row btw w-full"> |
| | | <div class="radio-options order row x-btw w-full"> |
| | | <?php |
| | | $order = [ |
| | | 'orderby' => [ |
| | | 'date' => 'Order by date created', |
| | | 'alphabetical' => 'Order alphabetically' |
| | | [ |
| | | 'slug' => 'date', |
| | | 'label' => 'Date Created', |
| | | 'icon' => 'calendar' |
| | | ], |
| | | [ |
| | | 'slug' => 'alphabetical', |
| | | 'label' => 'Alphabetically', |
| | | 'icon' => 'alphabetical', |
| | | ], |
| | | [ |
| | | 'slug' => 'date_modified', |
| | | 'icon' => 'clock-clockwise', |
| | | 'label' => 'Date Modified', |
| | | ], |
| | | ], |
| | | 'order' => [ |
| | | 'sort-ascending' => 'In ascending order (Z-A, oldest to newest)', |
| | | 'sort-descending' => 'In descending order (A-Z, newest to oldest)' |
| | | [ |
| | | 'slug' => 'desc', |
| | | 'icon' => 'sort-descending', |
| | | 'label' => 'Descending (A-Z, 1-10)' |
| | | ], |
| | | [ |
| | | 'slug' => 'asc', |
| | | 'icon' => 'sort-ascending', |
| | | 'label' => 'Ascending (Z-A, 10-1)' |
| | | ] |
| | | ] |
| | | ]; |
| | | |
| | | foreach ($order as $o => $option) { |
| | | ?> |
| | | <div class="row start"> |
| | | <div class="row left"> |
| | | <span class="label"><?= ucfirst($o)?>:</span> |
| | | <?php |
| | | $title = $o === 'orderby' ? 'Order by ' : 'Sort '; |
| | | $i = 0; |
| | | foreach ($option as $opt => $label) { |
| | | $icon = $opt === 'date' ? 'calendar' : $opt; |
| | | foreach ($option as $conf) { |
| | | ?> |
| | | <input id="<?=$opt?>" class="btn" type="radio" name="<?=$o?>" data-filter="<?=$o?>" value="<?=$opt?>"<?=$i===0 ? ' checked':''?>> |
| | | <input id="<?=$o.'-'.$conf['slug'] ?>" class="btn" type="radio" name="<?=$o?>" data-filter="<?=$o?>" value="<?=$conf['slug']?>"<?=$i===0 ? ' checked':''?>> |
| | | |
| | | <label for="<?=$opt?>" title="<?=$label?>"><?=jvbDashIcon($icon)?></label> |
| | | <label for="<?=$o.'-'.$conf['slug']?>" title="<?=$title.' '.$conf['label']?>"><?=jvbDashIcon($conf['icon'])?><span class="label"><?= $conf['label'] ?></span></label> |
| | | <?php |
| | | $i++; |
| | | } |
| | |
| | | return; |
| | | } |
| | | ?> |
| | | <div class="filters row start"> |
| | | <div class="filters row left"> |
| | | <span class="label">Filters:</span> |
| | | <?php |
| | | foreach ($this->filters as $key => $config) { |
| | |
| | | <label for="date-start" class="col"> |
| | | From |
| | | </label> |
| | | <input type="date" id="date-start" class="date-start"> |
| | | <input type="date" id="date-start" class="date-start" name="date-start"> |
| | | <label for="date-end" class="col"> |
| | | To |
| | | </label> |
| | | <input type="date" id="date-end" class="date-end"> |
| | | <input type="date" id="date-end" class="date-end" name="date-end"> |
| | | </div> |
| | | <div class="month-picker"> |
| | | <label> |
| | |
| | | $out = ''; |
| | | if (!empty($terms)) { |
| | | $out .= sprintf( |
| | | '<div class="row nowrap"><label for="filter-%s">%s<span class="screen-reader-text">Filter by %s</span></label> |
| | | '<div class="row nowrap"><label class="m-0" for="filter-%s">%s<span class="screen-reader-text">Filter by %s</span></label> |
| | | <select id="filter-%s" class="filter %s" name="%s" data-filter="taxonomies" data-taxonomy="%s"> |
| | | <option value="">by %s</option>', |
| | | $taxonomy, |
| | |
| | | foreach ($terms as $term) { |
| | | $out .= sprintf( |
| | | '<option value="%s">%s</option>', |
| | | esc_attr($term['term_id']), |
| | | esc_html($term['name']) |
| | | esc_attr(is_object($term) ? $term->term_id : $term['term_id']), |
| | | esc_html(is_object($term) ? $term->name : $term['name']) |
| | | ); |
| | | } |
| | | $out .= '</select></div>'; |
| | |
| | | */ |
| | | protected function getCommonTerms(string $taxonomy, ?string $limit = null):array { |
| | | if ($limit) { |
| | | if ($limit === 'user') { |
| | | if (Site::has('membership') && $limit === 'user') { |
| | | $manager = new UserTermsManager(); |
| | | return $manager->getUserTerms($this->user_id, $taxonomy); |
| | | return $manager->fetchUserTerms($this->user_id, $taxonomy); |
| | | } else { |
| | | $limit = (int)$limit; |
| | | } |
| | |
| | | ob_start(); |
| | | ?> |
| | | <details class="multi-select" title="Select columns" hidden> |
| | | <summary class="row start nowrap"> |
| | | <summary class="row left nowrap"> |
| | | <?= jvbDashIcon('columns') ?> |
| | | <span class="labels">Toggle Columns</span> |
| | | </summary> |
| | |
| | | return; |
| | | } |
| | | ?> |
| | | <div class="bulk-controls row nowrap btw"> |
| | | <div class="bulk-controls row nowrap x-btw"> |
| | | <div class="bulk-select"> |
| | | <input type="checkbox" id="select-all" class="select-all"> |
| | | <label for="select-all" class="row"><span>Select All</span><span class="selected-count" hidden></span></label> |
| | |
| | | <option value="<?=$control?>"<?=$disabled?>><?=$label?></option> |
| | | <?php |
| | | } |
| | | foreach ($this->taxonomies as $taxonomy => $config) { |
| | | |
| | | foreach ($this->taxonomies as $taxonomy =>$config) { |
| | | $registrar = Registrar::getInstance($taxonomy); |
| | | if (!$registrar) continue; |
| | | ?> |
| | | <option value="tax-<?=$taxonomy?>">Add to <?= JVB_TAXONOMY[$taxonomy]['singular']??$config['label'] ?></option> |
| | | <option value="tax-<?=$taxonomy?>" data-type="selector" data-single="<?=$registrar->getSingular()?>" data-plural="<?=$registrar->getPlural()?>" data-taxonomy="<?=$taxonomy?>">Add to <?= $registrar->getSingular() ?></option> |
| | | <?php |
| | | } |
| | | ?> |
| | |
| | | $temp = array_filter($this->fields, function ($field) { |
| | | return in_array($field, $this->timelineUniqueFields); |
| | | }, ARRAY_FILTER_USE_KEY); |
| | | jvbDump($temp); |
| | | $form = new MetaForm(); |
| | | |
| | | echo '<template class="timelineItem">'; |
| | | $form->renderImagePreview(null,['fields' => $temp]); |
| | | echo Form::renderImagePreview(null, $temp); |
| | | echo '</template>'; |
| | | } |
| | | if (!array_key_exists('empty', $templates)) { |
| | |
| | | ob_start(); |
| | | ?> |
| | | <div class="item-select"> |
| | | <input type="checkbox" class="select-item"> |
| | | <label class="select-item-label"> |
| | | <input type="checkbox" class="select-item" name="select-item" id="item"> |
| | | <label class="select-item-label" for="item"> |
| | | <span class="screen-reader-text">Select this <?= $this->singular ?></span> |
| | | </label> |
| | | </div> |
| | |
| | | } |
| | | ob_start(); |
| | | ?> |
| | | <div class="item-actions row btw abs"> |
| | | <div class="item-actions row x-btw abs"> |
| | | <?php |
| | | foreach ($this->itemActions as $action) { |
| | | $config = $this->defaultItemActions[$action]; |
| | |
| | | <div class="item <?=esc_attr($this->dataType)?> row nowrap"> |
| | | <?= $this->renderItemSelect()?> |
| | | <?=$this->renderImage() ?> |
| | | <div class="col start w-full"> |
| | | <?= $this->renderItemActions()?> |
| | | <div class="col top w-full"> |
| | | <h3 data-field="post_title"></h3> |
| | | <p data-attr="date"></p> |
| | | <p data-field="price"></p> |
| | | <div data-field="post_excerpt"></div> |
| | | <?= $this->renderItemActions()?> |
| | | </div> |
| | | </div> |
| | | </template> |
| | |
| | | <td class="field show-<?= esc_attr($name) ?>" data-field="<?= esc_attr($name) ?>" data-field-type="<?=$config['type']?>"<?=(in_array($name, $this->stuck)) ? ' data-stuck':''?>> |
| | | <?php |
| | | if (in_array('edit', $this->caps)) { |
| | | echo $makeThisDetailed ? '<details><summary class="row btw">See Value</summary>' : ''; |
| | | echo $this->meta->render('form', $name, $config); |
| | | echo $makeThisDetailed ? '<details><summary class="row x-btw">See Value</summary>' : ''; |
| | | if (in_array($config['type'], ['selector', 'taxonomy', 'post'])) { |
| | | $config['autocomplete'] = true; |
| | | } |
| | | |
| | | echo Form::render($name, '', $config); |
| | | echo $makeThisDetailed ? '</details>' : ''; |
| | | } else { |
| | | echo '<p></p>'; |
| | |
| | | $makeThisDetailed = (in_array($config['type'], $makeDetails)); |
| | | ?> |
| | | <td class="field show-<?= esc_attr($name) ?>" data-field="<?= esc_attr($name) ?>" data-field-type="<?=$config['type']?>"<?=(in_array($name, $this->stuck)) ? ' data-stuck':''?>> |
| | | <?= $makeThisDetailed ? '<details><summary class="row btw">See Value</summary>' : '' ?> |
| | | <?php $this->meta->render('form', $name, $config); ?> |
| | | <?= $makeThisDetailed ? '<details><summary class="row x-btw">See Value</summary>' : '' ?> |
| | | <?php |
| | | if (in_array($config['type'], ['selector', 'taxonomy', 'post'])) { |
| | | $config['autocomplete'] = true; |
| | | } |
| | | ?> |
| | | <?= Form::render($name, '', $config); ?> |
| | | <?= $makeThisDetailed ? '</details>' : '' ?> |
| | | </td> |
| | | <?php |
| | |
| | | $makeThisDetailed = (in_array($config['type'], $makeDetails)); |
| | | ?> |
| | | <td class="field show-<?= esc_attr($name) ?>" data-field="<?= esc_attr($name) ?>" data-field-type="<?=$config['type']?>"<?=(in_array($name, $this->stuck)) ? ' data-stuck':''?>> |
| | | <?= $makeThisDetailed ? '<details><summary class="row btw">See Value</summary>' : '' ?> |
| | | <?php $this->meta->render('form', $name, $config); ?> |
| | | <?= $makeThisDetailed ? '<details><summary class="row x-btw">See Value</summary>' : '' ?> |
| | | <?= Form::render($name, '', $config); ?> |
| | | <?= $makeThisDetailed ? '</details>' : '' ?> |
| | | </td> |
| | | <?php |
| | |
| | | protected function renderTableActions(): string { |
| | | ob_start(); |
| | | ?> |
| | | <div class="table-actions row btw nowrap"> |
| | | <div class="table-actions row x-btw nowrap"> |
| | | <?php if (count(array_intersect(['create', 'edit'], $this->caps)) > 0) { ?> |
| | | <?= jvbRenderToggleTextField( |
| | | 'vertical', |
| | |
| | | protected function renderStatusRadios(): string { |
| | | ob_start(); |
| | | ?> |
| | | <div class="radio-options status-options row"> |
| | | <div class="radio-options status-options row" data-field="post_status" data-field-type="radio"> |
| | | <?php foreach ($this->statuses as $status): |
| | | if ($status === 'all') continue; |
| | | if (!in_array($status, $this->allowedStatuses)) continue; |
| | | if (!array_key_exists($status, $this->allowedStatuses)) continue; |
| | | $config = $this->allowedStatuses[$status]; |
| | | ?> |
| | | |
| | |
| | | <span class="screen-reader-text"><?= esc_html($config['label']) ?></span> |
| | | </label> |
| | | <?php endforeach; ?> |
| | | <span class="validation-message" hidden role="alert"></span> |
| | | </div> |
| | | <?php |
| | | return ob_get_clean(); |
| | |
| | | <input type="hidden" name="form-id" value="<?=uniqid('new-')?>" /> |
| | | <input type="hidden" name="content" value="<?=$this->dataType?>" /> |
| | | <div class="fields"> |
| | | <div class="field-group radio-options row"> |
| | | <span>Status:</span> |
| | | <?php |
| | | $this->getApplicableStatuses('edit'); |
| | | ?> |
| | | </div> |
| | | <?php if (!$this->userCanPublish) { ?> |
| | | <p class="description">Your account needs to be verified before you can publish content.</p> |
| | | <?php } |
| | | <?php |
| | | if (!empty($this->statuses)) { |
| | | echo Form::render('post_status', '', $this->getStatusFieldConfig('edit-')); |
| | | } |
| | | |
| | | if (!empty($this->sections)) { |
| | | $tabs = []; |
| | | foreach ($this->sections as $slug => $config) { |
| | | foreach ($this->sections as $config) { |
| | | $slug = $config['slug']; |
| | | $section = []; |
| | | if (array_key_exists('icon', $config)) { |
| | | $section = [ |
| | |
| | | 'content' => '', |
| | | 'description' => $config['description']??'', |
| | | ], $section); |
| | | $icon = jvbSectionIcon($slug); |
| | | if ($icon !== '') { |
| | | $tabs[$slug]['icon'] = $icon; |
| | | } |
| | | } |
| | | } else { |
| | | $tabs = false; |
| | | } |
| | | |
| | | |
| | | $fields = $this->fields; |
| | | |
| | | if (!$this->isTimeline) { |
| | | $first = ['post_thumbnail', 'post_title', 'price']; |
| | | $first = $this->registrar->getType() === 'post' ? |
| | | ['post_thumbnail', 'post_title', 'price'] : |
| | | ( $this->registrar->getType() === 'term' ? |
| | | ['name', 'thumbnail', 'description'] : |
| | | ['username', 'display_name', 'description']); |
| | | |
| | | foreach ($first as $f) { |
| | | if (array_key_exists($f, $fields)) { |
| | | if ($tabs) { |
| | | $tabs['basic']['content'] .= $this->meta->render('form', $f, $fields[$f], false, true); |
| | | $tabs['basic']['content'] .= Form::render($f, '', $fields[$f]); |
| | | } else { |
| | | $this->meta->render('form', $f, $fields[$f]); |
| | | echo Form::render($f, '', $fields[$f]); |
| | | } |
| | | |
| | | unset($fields[$f]); |
| | | } |
| | | } |
| | | } |
| | | |
| | | if ($this->isTimeline) { |
| | | $temp = array_filter($fields, function ($field) { |
| | | return in_array($field, $this->timelineUniqueFields); |
| | | $temp = array_filter($fields, function ($field) use ($fields) { |
| | | return in_array($field, $this->timelineUniqueFields) && (!array_key_exists('hidden', $fields[$field]) || $fields[$field]['hidden'] === false); |
| | | }, ARRAY_FILTER_USE_KEY); |
| | | |
| | | $config = [ |
| | | 'type' => 'gallery', |
| | | 'type' => 'upload', |
| | | 'subtype' => 'timeline', |
| | | 'data' => 'timeline', |
| | | 'multiple' => true, |
| | | 'limit' => 0, |
| | | 'data' => ['timeline'], |
| | | 'label' => 'Progression', |
| | | 'fields' => $temp |
| | | ]; |
| | | $content = ''; |
| | | foreach ($fields as $slug=> $field) { |
| | | if (in_array($slug, $this->timelineSharedFields)) { |
| | | $content .= $this->form->render($slug, null, $field, false, true); |
| | | if (in_array($field['type'], ['taxonomy', 'selector'])) { |
| | | $field = array_merge($field, $this->taxConfig($field['taxonomy'], $field['label'])); |
| | | } |
| | | if (!array_key_exists('hidden', $field) || $field['hidden'] === false) { |
| | | $content .= Form::render($slug, '', $field); |
| | | } |
| | | } |
| | | } |
| | | |
| | | |
| | | $content .= $this->meta->render('form', 'timeline', $config, false,true); |
| | | $content .= Form::render('timeline_gallery', '', $config); |
| | | |
| | | $tabs['progression']['content'] = $content; |
| | | if ($tabs) { |
| | | $tabs['progression']['content'] = $content; |
| | | } else { |
| | | echo $content; |
| | | } |
| | | |
| | | $fields = $this->nonTimelineFields; |
| | | } |
| | | foreach ($fields as $n => $config) { |
| | | if (in_array($config['type'], ['taxonomy', 'selector'])) { |
| | | $config = array_merge($config, $this->taxConfig($config['taxonomy'], $config['label'])); |
| | | } |
| | | if ($tabs) { |
| | | $section = (array_key_exists('section', $config)) ? $config['section'] : 'basic'; |
| | | $tabs[$section]['content'] .= $this->meta->render('form', $n, $config, false, true); |
| | | $tabs[$section]['content'] .= Form::render($n, '', $config); |
| | | } else { |
| | | $this->meta->render('form', $n, $config); |
| | | echo Form::render($n, '', $config); |
| | | } |
| | | } |
| | | |
| | |
| | | </form> |
| | | <?php |
| | | return ob_get_clean(); |
| | | // return ''; |
| | | } |
| | | |
| | | protected function renderEditModal():void |
| | |
| | | <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> |
| | | <div class="fields"> |
| | | <div class="field-group radio-options row"> |
| | | <?php |
| | | $this->getApplicableStatuses('bulk-'); |
| | | ?> |
| | | </div> |
| | | <?php |
| | | echo Form::render('post_status', '', $this->getStatusFieldConfig('bulk-')); |
| | | |
| | | if (!empty($this->taxonomies)) { |
| | | ?> |
| | | <div class="taxonomies"> |
| | | <?php |
| | | foreach ($this->taxonomies as $taxonomy => $config) { |
| | | $this->meta->render( |
| | | 'form', |
| | | 'bulk-edit-'.$taxonomy, |
| | | [ |
| | | 'type' => 'taxonomy', |
| | | 'label' => $config['label'], |
| | | 'taxonomy' => $taxonomy, |
| | | 'createNew' => jvbUserIsVerified(), |
| | | 'multiple' => true, |
| | | 'mode' => 'append' |
| | | ] |
| | | ); |
| | | echo Form::render('bulk-edit-'.$taxonomy, '', $this->taxConfig($taxonomy, $config['label'])); |
| | | } |
| | | ?> |
| | | </div> |
| | |
| | | return array_key_exists('bulkEdit', $field); |
| | | }); |
| | | foreach ($fields as $fieldName => $config) { |
| | | $this->meta->render('form', $fieldName, $config); |
| | | echo Form::render($fieldName, '', $config); |
| | | } |
| | | ?> |
| | | </div> |
| | |
| | | ); |
| | | } |
| | | |
| | | protected function getStatusFieldConfig(string $prefix): array |
| | | { |
| | | $options = []; |
| | | foreach ($this->statuses as $status) { |
| | | if ($status === 'all' || !array_key_exists($status, $this->allowedStatuses)) { |
| | | continue; |
| | | } |
| | | $config = $this->allowedStatuses[$status]; |
| | | |
| | | if (in_array($status, ['future', 'past'])) { |
| | | if ($status === 'future') { |
| | | $status = 'publish'; |
| | | $config = ['icon' => 'eye', 'label' => 'Live']; |
| | | } else { |
| | | continue; |
| | | } |
| | | } |
| | | |
| | | $options[$status] = [ |
| | | 'label' => $config['label'], |
| | | 'icon' => $config['icon'], |
| | | 'disabled' => ($status === 'publish' && !$this->userCanPublish), |
| | | ]; |
| | | } |
| | | |
| | | return [ |
| | | 'type' => 'radio', |
| | | 'label' => 'Status', |
| | | 'options' => $options, |
| | | 'inputClass' => 'btn', |
| | | 'idPrefix' => $prefix, |
| | | 'class' => 'radio-options row', |
| | | 'hint' => !$this->userCanPublish |
| | | ? 'Your account needs to be verified before you can publish content.' |
| | | : '', |
| | | ]; |
| | | } |
| | | |
| | | protected function getApplicableStatuses(string $prefix) { |
| | | ob_start(); |
| | | foreach ($this->statuses as $status) { |
| | | if ($status === 'all' || !array_key_exists($status, $this->allowedStatuses)) { |
| | | continue; |
| | |
| | | </label> |
| | | <?php |
| | | } |
| | | $out = ob_get_clean(); |
| | | echo Form::fieldWrap('post_status', $out, ['type'=>'group']); |
| | | } |
| | | |
| | | |
| | | public static function searchFilter():string |
| | | { |
| | | $self = new self(); |
| | | $self->hasSearch = true; |
| | | ob_start(); |
| | | $self->renderSearch(); |
| | | return ob_get_clean(); |
| | | } |
| | | |
| | | public static function viewFilter(array $views):string |
| | | { |
| | | $self = new self(); |
| | | $self->views = $views; |
| | | ob_start(); |
| | | $self->renderViewControls(); |
| | | return ob_get_clean(); |
| | | } |
| | | |
| | | public static function orderFilter(bool $random = false):string |
| | | { |
| | | $self = new self(); |
| | | ob_start(); |
| | | $self->renderOrderControls(); |
| | | return ob_get_clean(); |
| | | } |
| | | } |