proUpsell()->registerHooks();
}
private function proUpsell(): ProUpsell
{
return $this->proUpsell ??= new ProUpsell();
}
public function enqueueAssets(string $hookSuffix): void
{
if ('woocommerce_page_' . self::PAGE !== $hookSuffix) {
return;
}
wp_enqueue_style(
'tabby-admin',
\Tabby\Plugin::instance()->url('assets/css/admin.css'),
[],
\Tabby\VERSION,
);
wp_enqueue_script(
'tabby-repeater',
\Tabby\Plugin::instance()->url('assets/js/repeater.js'),
[],
\Tabby\VERSION,
['in_footer' => true, 'strategy' => 'defer'],
);
}
public function addMenuPage(): void
{
add_submenu_page(
'woocommerce',
__('Tabvera - Product Tabs', 'tabvera'),
__('Tabvera Tabs', 'tabvera'),
'manage_woocommerce',
self::PAGE,
[$this, 'renderPage'],
);
}
public function registerSettings(): void
{
register_setting(
self::PAGE,
self::OPTION,
[
'type' => 'array',
'sanitize_callback' => [$this, 'sanitize'],
],
);
add_filter(
'option_page_capability_' . self::PAGE,
static fn (): string => 'manage_woocommerce',
);
}
public function renderPage(): void
{
if (! current_user_can('manage_woocommerce')) {
return;
}
$repo = new TabRepository();
$settings = $repo->settings();
$globalTabs = $repo->globalTabs();
$richContent = (bool) ($settings['rich_content'] ?? false);
?>
proUpsell()->banner(); ?>
proUpsell()->cards(); ?>
*/
public function sanitize(mixed $raw): array
{
if (! is_array($raw)) {
$raw = [];
}
/** @var array $defaults */
$defaults = require TABBY_DIR . 'config/defaults.php';
$globalTabs = [];
if (isset($raw['global_tabs']) && is_array($raw['global_tabs'])) {
$position = 0;
foreach ($raw['global_tabs'] as $entry) {
if (! is_array($entry)) {
continue;
}
$title = isset($entry['title']) ? sanitize_text_field((string) $entry['title']) : '';
if ('' === $title) {
continue;
}
$globalTabs[] = [
'id' => $this->uniqueSlug($title, $position, $globalTabs),
'title' => $title,
'content' => isset($entry['content']) ? wp_kses_post((string) $entry['content']) : '',
'enabled' => ! empty($entry['enabled']),
];
++$position;
}
}
return array_merge($defaults, [
'enabled' => ! empty($raw['enabled']),
'rich_content' => ! empty($raw['rich_content']),
'global_tabs' => $globalTabs,
]);
}
/**
* Build a slug for a global tab, ensuring it does not collide with earlier
* tabs in the same save.
*
* @param array> $existing
*/
private function uniqueSlug(string $title, int $position, array $existing): string
{
$base = sanitize_key($title);
if ('' === $base) {
$base = 'tab_' . $position;
}
$used = [];
foreach ($existing as $tab) {
if (isset($tab['id'])) {
$used[] = (string) $tab['id'];
}
}
$slug = $base;
$n = 1;
while (in_array($slug, $used, true)) {
$slug = $base . '_' . $n;
++$n;
}
return $slug;
}
}