GIF94; MINI MO Shell - Tarih Gösterimli

MINI MINI MANI MO - TARİH GÖSTERİMLİ

Path : /var/www/wordpress/wp-content/plugins/oxymade/includes/
File Upload :
Current File : /var/www/wordpress/wp-content/plugins/oxymade/includes/typography.php

<?php

namespace OxyMade\Typography;

/**
 * Typography configuration and management
 */
class TypographyManager {
    
    /**
     * Default typography configuration
     */
    const DEFAULT_CONFIG = [
        'typescale_enabled' => false,
        'fluid_enabled' => true,
        'base_font_size_mobile' => 16,
        'base_font_size_desktop' => 18,
        'typescale_mobile' => 1.25,
        'typescale_desktop' => 1.333,
        'custom_sizes' => []
    ];

    /**
     * Initialize typography manager
     */
    public static function init() {
        if (function_exists('add_action')) {
            add_action('wp_ajax_oxymade_save_typography_config', [self::class, 'ajax_save_typography_config']);
            add_action('wp_ajax_oxymade_get_typography_config', [self::class, 'ajax_get_typography_config']);
        }
    }

    /**
     * Get typography configuration
     */
    public static function get_config() {
        $config = function_exists('get_option') ? get_option('oxymade_typography_config', []) : [];
        
        // Merge with defaults, but prioritize saved values
        $merged_config = array_merge(self::DEFAULT_CONFIG, $config);
        
        // Ensure custom_sizes is always an array
        if (!isset($merged_config['custom_sizes']) || !is_array($merged_config['custom_sizes'])) {
            $merged_config['custom_sizes'] = [];
        }

        // Populate fluid_sizes from heading presets if empty
        if (empty($merged_config['fluid_sizes']) && function_exists('get_option')) {
            $presets = get_option('oxymade_heading_presets', []);
            if (!empty($presets)) {
                $fluid_sizes = [];
                foreach ($presets as $key => $preset) {
                    if (isset($preset['mobile']) && isset($preset['desktop'])) {
                        $fluid_sizes[$key] = [
                            'mobile' => (int) $preset['mobile'],
                            'desktop' => (int) $preset['desktop'],
                        ];
                    }
                }
                if (!empty($fluid_sizes)) {
                    $merged_config['fluid_sizes'] = $fluid_sizes;
                }
            }
        }

        return $merged_config;
    }
    
    /**
     * Save typography configuration
     */
    public static function save_config($config) {
        $sanitized_config = self::sanitize_config($config);
        
        if (function_exists('update_option')) {
            update_option('oxymade_typography_config', $sanitized_config);
            return true; // Always return true since we processed the config
        }
        
        return true;
    }
    
    /**
     * Sanitize configuration data
     */
    public static function sanitize_config($config) {
        $sanitized = [];
        
        // Handle boolean values that might come as strings from AJAX
        $sanitized['typescale_enabled'] = filter_var($config['typescale_enabled'] ?? false, FILTER_VALIDATE_BOOLEAN);
        $sanitized['fluid_enabled'] = filter_var($config['fluid_enabled'] ?? false, FILTER_VALIDATE_BOOLEAN);
        $sanitized['base_font_size_mobile'] = max(12, min(24, intval($config['base_font_size_mobile'] ?? 16)));
        $sanitized['base_font_size_desktop'] = max(14, min(32, intval($config['base_font_size_desktop'] ?? 18)));
        $sanitized['typescale_mobile'] = max(1.0, min(2.0, floatval($config['typescale_mobile'] ?? 1.25)));
        $sanitized['typescale_desktop'] = max(1.0, min(2.0, floatval($config['typescale_desktop'] ?? 1.333)));
        
        // Sanitize custom sizes - handle multiple mode data
        $sanitized['custom_sizes'] = [];
        $sanitized['fluid_sizes'] = [];
        $sanitized['custom_units_sizes'] = [];

        // Sanitize active custom_sizes
        if (!empty($config['custom_sizes']) && is_array($config['custom_sizes'])) {
            $sanitized['custom_sizes'] = self::sanitize_custom_sizes_array($config['custom_sizes']);
        }

        // Sanitize fluid_sizes
        if (!empty($config['fluid_sizes']) && is_array($config['fluid_sizes'])) {
            $sanitized['fluid_sizes'] = self::sanitize_custom_sizes_array($config['fluid_sizes']);
        }
        
        // Sanitize custom_units_sizes
        if (!empty($config['custom_units_sizes']) && is_array($config['custom_units_sizes'])) {
            $sanitized['custom_units_sizes'] = self::sanitize_custom_sizes_array($config['custom_units_sizes']);
        }
        
        return $sanitized;
    }
    
    /**
     * Sanitize custom sizes array
     */
    private static function sanitize_custom_sizes_array($sizes) {
        $sanitized = [];
        
        foreach ($sizes as $key => $size) {
            $sanitized_key = function_exists('sanitize_key') ? sanitize_key($key) : preg_replace('/[^a-z0-9_\-]/', '', strtolower($key));
            
            if (is_array($size)) {
                if (isset($size['mobile']) && isset($size['desktop'])) {
                    // Fluid custom sizes (mobile + desktop)
                    $mobile_val = intval($size['mobile']);
                    $desktop_val = intval($size['desktop']);
                    
                    // If values are 0 or empty, use defaults
                    if ($mobile_val <= 0 || $desktop_val <= 0) {
                        $defaults = self::get_default_custom_sizes();
                        if (isset($defaults[$key])) {
                            $mobile_val = $defaults[$key]['mobile'];
                            $desktop_val = $defaults[$key]['desktop'];
                        }
                    }
                    
                    $sanitized[$sanitized_key] = [
                        'mobile' => max(8, min(120, $mobile_val)),
                        'desktop' => max(8, min(200, $desktop_val))
                    ];
                } elseif (isset($size['value'])) {
                    // Fixed custom sizes (single value)
                    $value = sanitize_text_field($size['value']);
                    
                    // If value is empty, use default
                    if (empty($value)) {
                        $defaults = self::get_default_custom_sizes();
                        if (isset($defaults[$key])) {
                            $value = $defaults[$key]['value'];
                        }
                    }
                    
                    $sanitized[$sanitized_key] = [
                        'value' => $value
                    ];
                }
            }
        }
        
        return $sanitized;
    }
    
    /**
     * Extract heading preset sizes from design set global settings JSON
     *
     * @param array $typography_settings The settings.typography portion of the design set JSON
     * @return array Heading presets keyed by name (hero, h1-h6) with mobile/desktop/font_weight/line_height/letter_spacing
     */
    public static function extract_heading_presets_from_globals($typography_settings) {
        $presets = [];

        $typography_presets = $typography_settings['global_typography']['typography_presets'] ?? [];
        if (empty($typography_presets)) {
            return $presets;
        }

        // Map preset labels to heading names (multiple label variations per heading)
        $label_map = [
            'hero-heading' => 'hero', 'hero' => 'hero',
            'h1-heading' => 'h1', 'h1' => 'h1',
            'h2-heading' => 'h2', 'h2' => 'h2',
            'h3-heading' => 'h3', 'h3' => 'h3',
            'h4-heading' => 'h4', 'h4' => 'h4',
            'h5-heading' => 'h5', 'h5' => 'h5',
            'h6-heading' => 'h6', 'h6' => 'h6',
        ];

        foreach ($typography_presets as $preset_entry) {
            $label = $preset_entry['preset']['label'] ?? '';
            // Normalize: lowercase, trim, replace spaces/underscores with hyphens
            $normalized = strtolower(trim(str_replace([' ', '_'], '-', $label)));
            if (!isset($label_map[$normalized])) {
                continue;
            }

            $heading_name = $label_map[$normalized];
            $typo = $preset_entry['custom']['customTypography'] ?? [];

            $desktop = $typo['fontSize']['breakpoint_base']['number'] ?? null;
            $mobile = $typo['fontSize']['breakpoint_phone_portrait']['number'] ?? null;

            if ($desktop === null) {
                continue;
            }

            // If no mobile size, derive from desktop (roughly 60% for large, closer for small)
            if ($mobile === null) {
                $mobile = max(14, round($desktop * 0.6));
            }

            // Clean float precision in percentage strings (e.g. "110.00000000000001%" → "110%")
            $line_height = $typo['advanced']['lineHeight']['breakpoint_base']['style'] ?? null;
            $letter_spacing = $typo['advanced']['letterSpacing']['breakpoint_base']['style'] ?? null;
            if ($line_height !== null) {
                $line_height = preg_replace_callback('/[\d.]+/', fn($m) => rtrim(rtrim(number_format((float)$m[0], 2, '.', ''), '0'), '.'), $line_height);
            }
            if ($letter_spacing !== null) {
                $letter_spacing = preg_replace_callback('/[\d.]+/', fn($m) => rtrim(rtrim(number_format((float)$m[0], 2, '.', ''), '0'), '.'), $letter_spacing);
            }

            $presets[$heading_name] = [
                'mobile' => (int) $mobile,
                'desktop' => (int) $desktop,
                'font_weight' => $typo['fontWeight']['breakpoint_base'] ?? null,
                'line_height' => $line_height,
                'letter_spacing' => $letter_spacing,
            ];
        }

        return $presets;
    }

    /**
     * Generate typography variables based on configuration
     */
    public static function generate_typography_variables() {
        $config = self::get_config();

        // Get fluid_text_sizing from oxymade_settings (the toggle in Step 3)
        // This toggle ONLY affects text sizes (text-xs, text-sm, etc.), NOT headings
        $oxymade_settings = function_exists('get_option') ? get_option('oxymade_settings', []) : [];
        $fluid_text_sizing = isset($oxymade_settings['fluid_text_sizing']) ? $oxymade_settings['fluid_text_sizing'] : true;

        $variables = [];

        // Always use config-based heading generation
        if ($config['typescale_enabled']) {
            $heading_vars = self::generate_headings_with_typescale($config);
        } else {
            $heading_vars = self::generate_headings_custom($config);
        }

        // Generate TEXT SIZES (controlled by fluid text toggle ONLY, independent of heading settings)
        $text_vars = self::generate_text_sizes($config, $fluid_text_sizing);

        // Combine both
        $variables = array_merge($heading_vars, $text_vars);

        return $variables;
    }
    
    /**
     * Generate TEXT SIZES (controlled by fluid text toggle ONLY)
     */
    private static function generate_text_sizes($config, $fluid_text_sizing) {
        $variables = [];
        $custom_sizes = $config['custom_sizes'] ?? [];
        $default_sizes = self::get_default_custom_sizes();

        $text_names = [
            'text-xs',
            'text-sm',
            'text-base',
            'text-lg',
            'text-xl',
            'text-2xl',
            'text-3xl',
            'text-4xl',
            'text-5xl',
            'text-6xl',
            'text-7xl'
        ];

        foreach ($text_names as $name) {
            // Use custom sizes if available, otherwise use defaults from get_default_custom_sizes()
            if (isset($custom_sizes[$name]) && isset($custom_sizes[$name]['mobile']) && isset($custom_sizes[$name]['desktop'])) {
                $mobile = $custom_sizes[$name]['mobile'];
                $desktop = $custom_sizes[$name]['desktop'];
            } else {
                $mobile = $default_sizes[$name]['mobile'] ?? 16;
                $desktop = $default_sizes[$name]['desktop'] ?? 18;
            }

            // Use fluid_text_sizing toggle (independent of heading settings)
            if ($fluid_text_sizing) {
                $value = self::generate_fluid_value($mobile, $desktop);
            } else {
                $value = $desktop . 'px';
            }

            $variables[] = [
                'id' => 'om-' . $name,
                'type' => 'unit',
                'label' => self::format_typography_label($name),
                'cssVariableName' => $name,
                'collection' => 'OxyMade Typography',
                'value' => [
                    'number' => $value,
                    'unit' => 'custom',
                    'style' => $value
                ]
            ];
        }

        return $variables;
    }

    /**
     * Generate HEADINGS using typescale
     * Always generates clamp() values using calculated mobile/desktop sizes
     */
    private static function generate_headings_with_typescale($config) {
        $variables = [];
        $base_mobile = $config['base_font_size_mobile'];
        $base_desktop = $config['base_font_size_desktop'];
        $scale_mobile = $config['typescale_mobile'];
        $scale_desktop = $config['typescale_desktop'];

        $heading_levels = [
            'hero' => 6,
            'h1' => 5,
            'h2' => 4,
            'h3' => 3,
            'h4' => 2,
            'h5' => 1,
            'h6' => 0,
        ];

        foreach ($heading_levels as $name => $level) {
            $mobile_size = $base_mobile * pow($scale_mobile, $level);
            $desktop_size = $base_desktop * pow($scale_desktop, $level);

            $value = self::generate_fluid_value($mobile_size, $desktop_size);

            $variables[] = [
                'id' => 'om-' . $name,
                'type' => 'unit',
                'label' => self::format_typography_label($name),
                'cssVariableName' => $name,
                'collection' => 'OxyMade Typography',
                'value' => [
                    'number' => $value,
                    'unit' => 'custom',
                    'style' => $value
                ]
            ];
        }

        return $variables;
    }

    /**
     * Generate HEADINGS using custom/fluid/fixed settings (when typescale is OFF)
     */
    private static function generate_headings_custom($config) {
        $variables = [];
        $custom_sizes = $config['custom_sizes'] ?? [];
        $default_sizes = self::get_default_custom_sizes();

        $heading_levels = ['hero', 'h1', 'h2', 'h3', 'h4', 'h5', 'h6'];

        foreach ($heading_levels as $name) {
            // Custom Units mode: user provides a raw CSS value (e.g., "2.5rem", "clamp(...)")
            if (isset($custom_sizes[$name]['value']) && !empty($custom_sizes[$name]['value'])) {
                $value = $custom_sizes[$name]['value'];
            } else {
                // Fluid Custom mode: mobile/desktop pair → clamp() or fixed px
                if (isset($custom_sizes[$name]['mobile']) && isset($custom_sizes[$name]['desktop'])) {
                    $mobile = $custom_sizes[$name]['mobile'];
                    $desktop = $custom_sizes[$name]['desktop'];
                } else {
                    $mobile = $default_sizes[$name]['mobile'] ?? 16;
                    $desktop = $default_sizes[$name]['desktop'] ?? 18;
                }

                if ($config['fluid_enabled']) {
                    $value = self::generate_fluid_value($mobile, $desktop);
                } else {
                    $value = $desktop . 'px';
                }
            }

            $variables[] = [
                'id' => 'om-' . $name,
                'type' => 'unit',
                'label' => self::format_typography_label($name),
                'cssVariableName' => $name,
                'collection' => 'OxyMade Typography',
                'value' => [
                    'number' => $value,
                    'unit' => 'custom',
                    'style' => $value
                ]
            ];
        }

        return $variables;
    }

    /**
     * Generate fluid clamp() value
     * Note: Using 1rem = 10px for easier calculations
     */
    private static function generate_fluid_value($mobile, $desktop) {
        // Convert to rem for better scaling (1rem = 10px)
        $mobile_rem = $mobile / 10;
        $desktop_rem = $desktop / 10;

        // Calculate viewport width scaling
        $vw_scale = ($desktop_rem - $mobile_rem) / 61.25; // 61.25vw = 100vw - 38.75vw (mobile to desktop range)

        return sprintf('clamp(%.3frem, %.3frem + %.3fvw, %.3frem)',
            $mobile_rem,
            $mobile_rem,
            $vw_scale,
            $desktop_rem
        );
    }
    
    /**
     * Get default custom sizes
     */
    public static function get_default_custom_sizes() {
        return [
            'hero' => ['mobile' => 40, 'desktop' => 72, 'value' => '72px'],
            'h1' => ['mobile' => 32, 'desktop' => 48, 'value' => '48px'],
            'h2' => ['mobile' => 24, 'desktop' => 32, 'value' => '32px'],
            'h3' => ['mobile' => 20, 'desktop' => 28, 'value' => '28px'],
            'h4' => ['mobile' => 18, 'desktop' => 24, 'value' => '24px'],
            'h5' => ['mobile' => 16, 'desktop' => 20, 'value' => '20px'],
            'h6' => ['mobile' => 14, 'desktop' => 18, 'value' => '18px'],
            'text-xs' => ['mobile' => 12, 'desktop' => 12, 'value' => '12px'],
            'text-sm' => ['mobile' => 14, 'desktop' => 14, 'value' => '14px'],
            'text-base' => ['mobile' => 16, 'desktop' => 16, 'value' => '16px'],
            'text-lg' => ['mobile' => 17, 'desktop' => 18, 'value' => '18px'],
            'text-xl' => ['mobile' => 18, 'desktop' => 20, 'value' => '20px'],
            'text-2xl' => ['mobile' => 20, 'desktop' => 24, 'value' => '24px'],
            'text-3xl' => ['mobile' => 24, 'desktop' => 30, 'value' => '30px'],
            'text-4xl' => ['mobile' => 30, 'desktop' => 36, 'value' => '36px'],
            'text-5xl' => ['mobile' => 38, 'desktop' => 48, 'value' => '48px'],
            'text-6xl' => ['mobile' => 48, 'desktop' => 60, 'value' => '60px'],
            'text-7xl' => ['mobile' => 56, 'desktop' => 72, 'value' => '72px']
        ];
    }
    
    /**
     * Format typography label
     */
    private static function format_typography_label($name) {
        $label = str_replace('-', ' ', $name);
        $label = ucwords($label);
        return $label;
    }

    /**
     * AJAX handler for saving typography configuration
     */
    public static function ajax_save_typography_config() {
        if (!isset($_POST['nonce']) || !wp_verify_nonce($_POST['nonce'], 'oxymade-admin-nonce')) {
            wp_send_json_error('Invalid security token');
            exit;
        }

        if (!current_user_can('manage_options')) {
            wp_send_json_error('You do not have permission to perform this action');
            exit;
        }

        $config = $_POST['config'] ?? [];
        $result = self::save_config($config);

        if ($result) {
            // Auto-apply: re-sync typography variables with Oxygen
            if (class_exists('\\OxyMade\\Variables\\VariableManager')) {
                \OxyMade\Variables\VariableManager::sync_typography_with_oxygen('add_new');
            }

            wp_send_json_success(['message' => 'Typography configuration saved and applied!']);
        } else {
            wp_send_json_error('Failed to save typography configuration');
        }

        exit;
    }

    /**
     * AJAX handler for getting typography configuration
     */
    public static function ajax_get_typography_config() {
        if (!isset($_POST['nonce']) || !wp_verify_nonce($_POST['nonce'], 'oxymade-admin-nonce')) {
            wp_send_json_error('Invalid security token');
            exit;
        }

        if (!current_user_can('manage_options')) {
            wp_send_json_error('You do not have permission to perform this action');
            exit;
        }

        $config = self::get_config();
        wp_send_json_success(['config' => $config]);

        exit;
    }
}

// Initialize the typography manager
TypographyManager::init();

OHA YOOO - Tarih: 2026-08-04 00:03:15