user = wp_get_current_user();
$this->user_id = $this->user->ID;
$this->config = JVB_CONTENT[$content];
$this->singular = $this->config['singular'];
$this->plural = $this->config['plural'];
$this->content = $content;
$this->fields = jvbGetFields($this->content, 'post');
$this->sections = jvbGetSections($this->content, 'post');
$this->stuck = [
'post_title',
'term_name'
];
$this->init();
}
protected function init():void
{
$this->initStatuses();
$this->initBulkActions();
$this->initTaxonomies();
$this->initFilters();
$this->meta = new MetaManager(null, 'post', $this->content);
$plural = strtolower($this->config['plural']??$this->content.'s');
$this->userCanPublish = (jvbUserIsVerified()) ?
user_can($this->user_id, "publish_{$plural}") : false;
}
protected function initTaxonomies():void
{
$this->taxonomies = array_filter(JVB_TAXONOMY, function ($config) {
return in_array($this->content, $config['for_content']);
});
}
protected function initStatuses():void
{
$this->statuses = (array_key_exists('is_calendar', $this->config)) ?
[
'all' => [
'icon' => 'calendar',
'label' => 'Everything',
],
'future'=> [
'label' => 'Upcoming',
'icon' => 'future',
],
'past' => [
'label' => 'Past',
'icon' => 'past',
],
'repeat'=> [
'label' => 'Recurring',
'icon' => 'repeat',
],
'draft' => [
'icon' => 'hide',
'label' => 'Hidden',
],
'trash' => [
'label' => 'Scrapped',
'icon' => 'delete',
],
] :
[
'all' => [
'icon' => 'all',
'label' => 'Everything',
],
'publish'=> [
'icon' => 'publish',
'label' => 'Live',
],
'draft' => [
'icon' => 'hide',
'label' => 'Hidden',
],
'trash' => [
'label' => 'Scrapped',
'icon' => 'delete',
],
];
}
protected function initBulkActions():void
{
$this->bulkActions = [
'edit' => 'Edit',
'publish' => 'Show',
'draft' => 'Hide',
// 'copy' => 'Duplicate',
'trash' => 'Scrap'
];
}
protected function initFilters():void
{
$this->filters = [
'status' => $this->statuses,
'date' => [
'label' => 'Date',
'icon' => 'calendar'
]
];
foreach ($this->taxonomies as $taxonomy=> $config) {
$this->filters['taxonomy'][$taxonomy] = [
'label' => $config['singular'],
'icon' => $taxonomy
];
}
}
public function render():void
{
ob_start();
?>
renderHeader();
$this->renderContent();
$this->renderModals();
$this->renderTemplates();
?>
Your = $this->config['plural'] ?>
config)) {
?>
=$this->config['page_description']?>
renderHeaderActions();
}
protected function renderHeaderActions():void
{
$uploadConfig = [
'type' => 'upload',
'subtype' => 'image',
'mode' => (jvbCheck('single_image', $this->config)) ? 'direct' : 'selection',
'create_new' => true,
'label' => (array_key_exists('image_title', $this->config)) ? $this->config['image_title'] : 'Upload More '.$this->config['plural'],
'content' => $this->content,
'singular' => $this->singular,
'plural' => $this->plural,
'multiple' => true,
'destination' => 'post'
];
if (!jvbCheck('single_image', $this->config)) {
$uploadConfig['destination'] = 'post_group';
}
$uploadConfig['destination'] = 'post_group';
if (!jvbCheck('single_image', $this->config)) {
$uploadConfig['group_title'] = 'Create '.$this->config['plural'];
$uploadConfig['group_description'] = 'Drag images into groups. Each group becomes its own '.$this->singular.'.
You can also select multiple images and click the "Add to Group" button.
If a '.$this->singular.' has multiple images, you can select the '.jvbIcon('star').' to set an image as the main one.
Images left ungrouped will become individual '.$this->plural.'
Once finished, click the \'Save Changes\' button to send to server for processing.
';
} else {
$uploadConfig['description'] = 'Each image will become its own '.$this->singular.'.';
}
?>
=jvbIcon('add') ?>Create New = $this->singular?>
= $this->config['upload_title'] ?? 'Bulk Upload '.$this->plural?>
meta->render(
'form',
'new_'.$this->content,
$uploadConfig
);
?>
renderFilters();
$this->renderBulkControls();
?>
renderEmptyState(), $this->content);
echo ''.$state.' ';
?>
=jvbIcon($this->content)?>Nothing here=jvbIcon($this->content)?>
It doesn't look like you have any =$this->config['plural'] ?> yet.
Add many by uploading images above. , or click the "=jvbIcon('add')?>" button to add one at a time.
Search:
= jvbSearch() ?>
renderViewFilters();
$this->renderStatusFilters();
$this->renderOrderFilters();
?>
Filters:
renderTaxonomyFilters();
$this->renderDateFilters();
?>
= jvbIcon('close', ['title' => 'Clear']); ?>
Clear All Filters
= $this->renderColumnSelector(); ?>
statuses)) {
return;
}
?>
Status:
statuses as $status => $config) {
$checked = ($i == 1) ? ' checked' : '';
?>
>
= jvbIcon($config['icon']) ?>
=$config['label']?>
View:
['icon' => 'grid', 'label' => 'Grid View'],
'list' => ['icon' => 'list', 'label' => 'List View'],
'table' => ['icon' => 'table', 'label' => 'Table View']
];
$first = true;
foreach ($views as $view => $config):
?>
>
= jvbIcon($config['icon']) ?>
= esc_html($config['label']) ?>
= jvbIcon('columns') ?>
Toggle Columns
fields as $fieldName => $config):
if (array_key_exists('hidden', $config)){
continue;
}
?>
= esc_html($config['label']) ?>
taxonomies)) {
return;
}
$out = '';
foreach ($this->taxonomies as $taxonomy => $config) {
$terms = $this->getCommonTerms($taxonomy);
if (!empty($terms)) {
$out .= sprintf(
'%sFilter by %s
by %s ',
$taxonomy,
jvbIcon($config['icon'], ['title' => $config['plural']]),
esc_html($config['plural']),
$taxonomy,
$taxonomy,
$taxonomy,
$taxonomy,
$config['plural']
);
foreach ($terms as $term) {
$out .= sprintf(
'%s ',
esc_attr($term['term_id']),
esc_html($term['name'])
);
}
$out .= '
';
}
}
echo $out;
}
/**
* Get common terms for taxonomy
* @param string $taxonomy
* @return array
*/
protected function getCommonTerms(string $taxonomy):array {
$manager = new UserTermsManager();
return $manager->getUserTerms($this->user_id, $taxonomy);
}
protected function renderDateFilters():void
{
$postType = jvbCheckBase($this->content);
// Get available months
global $wpdb;
$months = $wpdb->get_results("
SELECT DISTINCT
YEAR(post_date) as year,
MONTH(post_date) as month
FROM $wpdb->posts
WHERE post_type = '{$postType}'
AND post_author = '{$this->user_id}'
ORDER BY post_date DESC
");
// Quick filters
$out = '
'.
jvbIcon('calendar',['title'=>'Date']).
'by Date
by Date
Today
Past Week
Past Month
Past Year
Custom Range...
';
$form = '
From
To
Or select month
. . . ';
foreach ($months as $date) {
$month_name = date('F Y', mktime(0, 0, 0, $date->month, 1, $date->year));
$value = $date->year . '-' . str_pad($date->month, 2, '0', STR_PAD_LEFT);
$form .= sprintf(
'%s ',
esc_attr($value),
esc_html($month_name)
);
}
$form .= '
';
// Custom date range
$out .= jvbNewModal(
'date-range',
'Filter Results by Date:',
$form
);
echo $out;
}
protected function renderBulkControls():void
{
if (empty($this->bulkActions)) {
return;
}
?>
Bulk Actions...
bulkActions as $control => $label) {
$disabled = ($control === 'publish' && !$this->userCanPublish) ? ' disabled' : '';
?>
>=$label?>
taxonomies as $taxonomy => $config) {
?>
Add to = $config['singular'] ?>
Bulk Actions...
Restore
Permanently Delete
renderCreateModal();
$this->renderEditModal();
$this->renderBulkEditModal();
}
protected function renderCreateModal():void
{
echo jvbNewModal(
'create',
'Creating New '.$this->config['singular'],
str_replace('edit-form"', 'create-form" data-noautosave', $this->editForm())
);
}
protected function editForm():string
{
ob_start();
?>
statuses as $status => $config) {
if ($status === 'all') {
continue;
}
if (in_array($status, ['future', 'past'])) {
if ($status === 'future') {
$status = 'publish';
$config = [
'icon' => 'publish',
'label' => 'Live',
];
} else {
continue;
}
}
$disabled = ($status === 'publish' && !$this->userCanPublish) ? ' disabled' : '';
?>
>
= jvbIcon($config['icon'], ['title' => $config['label']]) ?>
= esc_html($config['label'])?>
singular,
$this->editForm()
);
}
protected function renderBulkEditModal():void
{
if (empty($this->bulkActions)) return;
ob_start();
?>
'.$this->config['plural'],
$form
);
}
protected function renderTemplates():void
{
$this->renderListView();
$this->renderGridView();
$this->renderTableView();
$this->renderTableRow();
echo jvbGetEmptyStateTemplate();
echo jvbGetGalleryPreviewTemplate();
}
protected function renderItemSelect():string
{
ob_start();
?>
Select this = $this->singular ?>
=jvbIcon('edit')?>
Edit = $this->singular ?>
=jvbIcon('delete')?>
Scrap = $this->singular ?>
singular ?>
fields as $name => $config) {
$renderMode = $form ? 'form' : 'render';
$field = $this->meta->render($renderMode, $name, $config, false, true);
// Special handling for title in grid view
if ($name === 'post_title' && !$form) {
$field = str_replace('', '', $field));
}
echo $field;
}
return ob_get_clean();
}
protected function renderGridView():void
{
?>
= $this->renderImage() ?>
= $this->renderItemActions(); ?>
= $this->renderItemSelect()?>
=$this->renderImage() ?>
= $this->renderItemActions()?>
= $this->renderItemSelect() ?>
= $this->renderStatusRadios() ?>
fields as $name => $config):
if (array_key_exists('hidden', $config)){
continue;
}
$makeThisDetailed = (in_array($config['type'], $makeDetails));
?>
stuck)) ? ' data-stuck':''?>>
= $makeThisDetailed ? 'See Value ' : '' ?>
meta->render('form', $name, $config); ?>
= $makeThisDetailed ? ' ' : '' ?>
statuses as $status => $config):
if ($status === 'all') continue;
// Handle special cases
if ($status === 'future') {
$status = 'publish';
$config = [
'icon' => 'publish',
'label' => 'Live'
];
} elseif ($status === 'past') {
continue;
}
?>
= jvbIcon($config['icon']) ?>
= esc_html($config['label']) ?>
fields as $name => $config):
if (array_key_exists('hidden', $config)){
continue;
}
?>
stuck)) ? ' data-stuck':''?>>
= esc_html($config['label']) ?>
= jvbRenderToggleTextField(
'vertical',
'TAB NAV:',
'',
jvbIcon('down'),
jvbIcon('right')
) ?>
= jvbIcon('add') ?>
Add Row