1168 lines
45 KiB
PHP
1168 lines
45 KiB
PHP
<?php
|
|
|
|
|
|
|
|
|
|
include get_template_directory() . '/includes/classes/wp-hooks.php';
|
|
|
|
|
|
//include get_template_directory(). '/includes/blocks/lcp-gallery/lcp-gallery.php';
|
|
include get_template_directory() . '/includes/classes/blocks.php';
|
|
new Lcp_Blocks();
|
|
|
|
|
|
// Include backend php
|
|
include get_template_directory() . '/includes/classes/backend.php';
|
|
|
|
|
|
function lcp_block_theme_setup() {
|
|
add_theme_support( 'block-templates' );
|
|
}
|
|
add_action( 'after_setup_theme', 'lcp_block_theme_setup' );
|
|
/* Add Styles */
|
|
function lcp_header_height_style() {
|
|
// Fetch the lcp_header_height value from wp_options.
|
|
$header_height = get_option('lcp_header_height', 0); // Default to 0 if not found
|
|
|
|
// Ensure we have a valid value
|
|
if ($header_height) {
|
|
// Output the inline style tag with the CSS variable for header height
|
|
echo "<style>:root { --lcp--header--height: {$header_height}px; }</style>";
|
|
}
|
|
}
|
|
add_action('wp_enqueue_scripts', 'lcp_header_height_style',1);
|
|
|
|
|
|
function lcp_enqueue() {
|
|
// Enqueue the theme's main stylesheet (style.css)
|
|
wp_enqueue_style('lcp-style', get_stylesheet_uri());
|
|
wp_enqueue_script('lcp-script', get_template_directory_uri() . '/assets/js/lcp.js');
|
|
wp_enqueue_script('lcp-ui-script', get_template_directory_uri() . '/assets/js/lcp-ui.js');
|
|
|
|
}
|
|
|
|
add_action('wp_enqueue_scripts', 'lcp_enqueue');
|
|
|
|
|
|
|
|
|
|
|
|
/* KEY POINTS */
|
|
function add_key_points_meta_box() {
|
|
add_meta_box(
|
|
'key_points_meta_box', // ID of the meta box
|
|
'Key Points', // Title of the meta box
|
|
'render_key_points_meta_box', // Callback function to display the meta box
|
|
'post', // Post type (you can change it to other post types)
|
|
'normal', // Context (normal, side, advanced)
|
|
'default' // Priority
|
|
);
|
|
}
|
|
// Add meta box if setting is turned on
|
|
$options = get_option('lcp_theme_settings', array());
|
|
$enable_key_points_meta = isset($options['enable_key_points_meta']) ? $options['enable_key_points_meta'] : 0;
|
|
|
|
// Check if 'enable_key_points_meta' is enabled (1), then add the meta box
|
|
if ($enable_key_points_meta) {
|
|
// Hook into add_meta_boxes to register the custom meta box
|
|
add_action('add_meta_boxes', 'add_key_points_meta_box');
|
|
}
|
|
|
|
// Sanitize the SVGs data
|
|
function lcp_custom_svgs_sanitize($input) {
|
|
// Ensure the input is an array
|
|
if (is_array($input)) {
|
|
foreach ($input as $key => $svg) {
|
|
// Sanitize the name and path for each SVG
|
|
if (isset($svg['name'])) {
|
|
$input[$key]['name'] = sanitize_text_field($svg['name']);
|
|
}
|
|
if (isset($svg['path'])) {
|
|
$input[$key]['path'] = sanitize_textarea_field($svg['path']);
|
|
}
|
|
}
|
|
}
|
|
|
|
return $input;
|
|
}
|
|
|
|
// Existing function to render the theme settings page
|
|
|
|
// Callback function to render the meta box
|
|
function render_key_points_meta_box($post) {
|
|
// Retrieve the stored key points (serialized data)
|
|
$key_points_serialized = get_post_meta($post->ID, '_key_points', true);
|
|
$key_points = !empty($key_points_serialized) ? unserialize($key_points_serialized) : [];
|
|
?>
|
|
<div id="key-points-repeater">
|
|
<ul id="key-points-list">
|
|
<?php foreach ($key_points as $index => $point) : ?>
|
|
<li class="key-point">
|
|
<input type="text" name="key_points[<?php echo $index; ?>]" value="<?php echo esc_attr($point); ?>" class="key-point-input" />
|
|
<button type="button" class="remove-key-point">Remove</button>
|
|
</li>
|
|
<?php endforeach; ?>
|
|
</ul>
|
|
<button type="button" id="add-key-point">Add Key Point</button>
|
|
</div>
|
|
<script>
|
|
document.addEventListener('DOMContentLoaded', function () {
|
|
const addButton = document.getElementById('add-key-point');
|
|
const keyPointsList = document.getElementById('key-points-list');
|
|
|
|
// Function to add a new key point input field
|
|
addButton.addEventListener('click', function () {
|
|
const index = keyPointsList.children.length;
|
|
const newItem = document.createElement('li');
|
|
newItem.classList.add('key-point');
|
|
|
|
newItem.innerHTML = `
|
|
<input type="text" name="key_points[${index}]" value="" class="key-point-input" />
|
|
<button type="button" class="remove-key-point">Remove</button>
|
|
`;
|
|
keyPointsList.appendChild(newItem);
|
|
});
|
|
|
|
// Function to remove a key point input field
|
|
keyPointsList.addEventListener('click', function (e) {
|
|
if (e.target && e.target.classList.contains('remove-key-point')) {
|
|
e.target.closest('.key-point').remove();
|
|
}
|
|
});
|
|
});
|
|
</script>
|
|
<?php
|
|
}
|
|
|
|
// Save the meta box data
|
|
function save_key_points_meta_box($post_id) {
|
|
// Check if this is an autosave or if the nonce is missing
|
|
if (defined('DOING_AUTOSAVE') && DOING_AUTOSAVE) return $post_id;
|
|
if (!isset($_POST['key_points'])) return $post_id;
|
|
|
|
// Sanitize and store the key points as a serialized array
|
|
$key_points = array_map('sanitize_text_field', $_POST['key_points']);
|
|
update_post_meta($post_id, 'key_points', serialize($key_points)); // Use serialize instead of json_encode
|
|
}
|
|
add_action('save_post', 'save_key_points_meta_box');
|
|
|
|
|
|
|
|
// Hook the function to the theme activation process
|
|
|
|
|
|
// Function to drop the lcp_icons table when the theme is deactivated
|
|
function drop_lcp_icons_table() {
|
|
global $wpdb;
|
|
|
|
// Table name with WordPress prefix
|
|
$table_name = $wpdb->prefix . 'lcp_icons';
|
|
|
|
// SQL query to drop the table
|
|
$sql = "DROP TABLE IF EXISTS $table_name;";
|
|
|
|
// Execute the query
|
|
$wpdb->query($sql);
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
// Function to read and display icon sets from the JSON file
|
|
// Function to read and display icon sets from the JSON file
|
|
function lcp_display_icon_sets() {
|
|
// Path to the JSON file
|
|
$json_path = get_template_directory() . '/assets/json/icons/icon-definitions.json';
|
|
|
|
// Check if the file exists
|
|
if (file_exists($json_path)) {
|
|
// Get the contents of the JSON file
|
|
$json_data = file_get_contents($json_path);
|
|
|
|
// Decode JSON data into a PHP array
|
|
$icon_sets = json_decode($json_data, true);
|
|
|
|
// Loop through the icon sets and output HTML
|
|
foreach ($icon_sets as $icon_set) {
|
|
?>
|
|
<div class="icon-set">
|
|
<h3><?php echo esc_html($icon_set['setFamily'] . ' - ' . $icon_set['setName']); ?></h3>
|
|
|
|
<!-- Add data-icon-set-id attribute to the Install and Uninstall buttons -->
|
|
<button class="install-btn" data-icon-set-id="<?php echo esc_attr($icon_set['id']); ?>">Install</button>
|
|
<button class="uninstall-btn" data-icon-set-id="<?php echo esc_attr($icon_set['id']); ?>">Uninstall</button>
|
|
</div>
|
|
<?php
|
|
}
|
|
} else {
|
|
echo '<p>' . esc_html__('No icon definitions found.', 'lcp') . '</p>';
|
|
}
|
|
}
|
|
|
|
|
|
// Enqueue the dashboard styles only on the icon-management page
|
|
function lcp_enqueue_dashboard_styles($hook) {
|
|
|
|
|
|
// Enqueue CSS for the dashboard
|
|
wp_enqueue_style(
|
|
'lcp-dashboard-css',
|
|
get_template_directory_uri() . '/assets/css/dashboard.css'
|
|
);
|
|
}
|
|
add_action('admin_enqueue_scripts', 'lcp_enqueue_dashboard_styles');
|
|
|
|
|
|
// Handle the AJAX request for installing icon sets
|
|
function lcp_install_icon_set($defaults = false) {
|
|
$json_path = get_template_directory() . '/assets/json/icons/icon-definitions.json';
|
|
|
|
if ($defaults) {
|
|
// Import only the default icons
|
|
if (file_exists($json_path)) {
|
|
$json_data = file_get_contents($json_path);
|
|
$icon_sets = json_decode($json_data, true);
|
|
|
|
// Loop through all icon sets and filter for default icons
|
|
foreach ($icon_sets as $icon_set) {
|
|
if (isset($icon_set['default']) && $icon_set['default'] === true) {
|
|
$file_name = $icon_set['fileName']; // Assuming the JSON structure has 'fileName' key
|
|
$icon_file_path = get_template_directory() . '/assets/json/icons/' . $file_name;
|
|
|
|
if (file_exists($icon_file_path)) {
|
|
$icon_data = file_get_contents($icon_file_path);
|
|
$icon_json = json_decode($icon_data, true);
|
|
|
|
// Check if svgs exist and process them
|
|
if (isset($icon_json[0]['svgs']) && is_array($icon_json[0]['svgs'])) {
|
|
foreach ($icon_json[0]['svgs'] as $svg) {
|
|
global $wpdb;
|
|
$table_name = $wpdb->prefix . 'lcp_icons';
|
|
|
|
// Insert the SVG data into the database
|
|
$wpdb->insert(
|
|
$table_name,
|
|
array(
|
|
'icon_name' => $svg['name'],
|
|
'icon_set_id' => $icon_set['id'],
|
|
'icon_family' => $icon_set['setFamily'],
|
|
'icon_version' => $icon_set['version'],
|
|
'paths' => ($svg['paths']),
|
|
'viewbox' => sanitize_text_field($svg['viewBox']),
|
|
'icon_id' => sanitize_text_field($svg['id']),
|
|
)
|
|
);
|
|
}
|
|
} else {
|
|
wp_send_json_error(array('message' => 'SVGs data not found in the JSON file.'));
|
|
}
|
|
} else {
|
|
wp_send_json_error(array('message' => 'SVG file for default set not found.'));
|
|
}
|
|
}
|
|
}
|
|
|
|
} else {
|
|
wp_send_json_error(array('message' => 'Icon definitions file not found.'));
|
|
}
|
|
} elseif (isset($_POST['icon_set_id'])) {
|
|
// Default behavior - check for icon_set_id in $_POST
|
|
if (!isset($_POST['icon_set_id'])) {
|
|
wp_send_json_error(array('message' => 'Invalid icon set ID.'));
|
|
}
|
|
|
|
$icon_set_id = intval($_POST['icon_set_id']);
|
|
|
|
// Create the database table if it doesn't exist
|
|
lcp_create_icons_table();
|
|
|
|
// Read the icon definitions JSON file
|
|
if (file_exists($json_path)) {
|
|
$json_data = file_get_contents($json_path);
|
|
$icon_sets = json_decode($json_data, true);
|
|
|
|
// Search for the selected icon set by ID
|
|
$selected_icon_set = null;
|
|
foreach ($icon_sets as $icon_set) {
|
|
if ($icon_set['id'] === $icon_set_id) {
|
|
$selected_icon_set = $icon_set;
|
|
break;
|
|
}
|
|
}
|
|
|
|
// If the icon set is found
|
|
if ($selected_icon_set) {
|
|
$file_name = $selected_icon_set['fileName']; // Assuming the JSON structure has 'fileName' key
|
|
$icon_file_path = get_template_directory() . '/assets/json/icons/' . $file_name;
|
|
|
|
// Now read the corresponding SVG file for the icon set
|
|
if (file_exists($icon_file_path)) {
|
|
$icon_data = file_get_contents($icon_file_path);
|
|
$icon_json = json_decode($icon_data, true);
|
|
|
|
// Check the structure of the decoded JSON
|
|
if (is_array($icon_json)) {
|
|
error_log(print_r($icon_json, true)); // Logs to PHP error log for inspection
|
|
}
|
|
|
|
// Loop through svgs if it exists and is an array
|
|
if (isset($icon_json[0]['svgs']) && is_array($icon_json[0]['svgs'])) {
|
|
foreach ($icon_json[0]['svgs'] as $svg) {
|
|
global $wpdb;
|
|
$table_name = $wpdb->prefix . 'lcp_icons';
|
|
|
|
// Insert each SVG data into the database
|
|
$wpdb->insert(
|
|
$table_name,
|
|
array(
|
|
'icon_name' => $svg['name'],
|
|
'icon_set_id' => $selected_icon_set['id'],
|
|
'icon_family' => $selected_icon_set['setFamily'],
|
|
'icon_version' => $selected_icon_set['version'],
|
|
'paths' => ($svg['paths']),
|
|
'viewbox' => sanitize_text_field($svg['viewBox']),
|
|
'icon_id' => sanitize_text_field($svg['id']),
|
|
)
|
|
);
|
|
}
|
|
|
|
wp_send_json_success(array('message' => 'Icon set installed and rows added with actual data.'));
|
|
} else {
|
|
wp_send_json_error(array('message' => 'SVGs data not found in the JSON file.'));
|
|
}
|
|
} else {
|
|
wp_send_json_error(array('message' => 'SVG file not found.'));
|
|
}
|
|
} else {
|
|
wp_send_json_error(array('message' => 'Icon set not found.'));
|
|
}
|
|
} else {
|
|
wp_send_json_error(array('message' => 'Icon definitions not found.'));
|
|
}
|
|
}
|
|
}
|
|
|
|
add_action('wp_ajax_install_icon_set', 'lcp_install_icon_set');
|
|
|
|
|
|
|
|
// Function to create the icons table in the database if it doesn't exist
|
|
function lcp_create_icons_table() {
|
|
global $wpdb;
|
|
|
|
$table_name = $wpdb->prefix . 'lcp_icons';
|
|
$charset_collate = $wpdb->get_charset_collate();
|
|
|
|
// SQL to create the table if it doesn't exist
|
|
$sql = "CREATE TABLE IF NOT EXISTS $table_name (
|
|
id BIGINT(20) UNSIGNED NOT NULL AUTO_INCREMENT, -- Auto-increment for the ID
|
|
icon_name VARCHAR(255),
|
|
icon_set_id VARCHAR(255),
|
|
icon_family VARCHAR(255),
|
|
icon_version VARCHAR(50),
|
|
paths TEXT,
|
|
viewbox VARCHAR(50),
|
|
icon_id VARCHAR(255) UNIQUE, -- Unique identifier for each SVG (based on SVG 'id')
|
|
PRIMARY KEY (id)
|
|
) $charset_collate;";
|
|
|
|
// Include the necessary WordPress file to run dbDelta
|
|
require_once(ABSPATH . 'wp-admin/includes/upgrade.php');
|
|
dbDelta($sql);
|
|
}
|
|
|
|
|
|
|
|
|
|
// Handle the AJAX request for uninstalling icon sets
|
|
function lcp_uninstall_icon_set() {
|
|
// Ensure icon set ID is passed in the request
|
|
if (!isset($_POST['icon_set_id'])) {
|
|
wp_send_json_error(array('message' => 'Invalid icon set ID.'));
|
|
}
|
|
|
|
// Get the icon set ID from the request
|
|
$icon_set_id = intval($_POST['icon_set_id']); // Ensure it's an integer
|
|
|
|
global $wpdb;
|
|
|
|
// Define the table name
|
|
$table_name = $wpdb->prefix . 'lcp_icons';
|
|
|
|
// Delete all rows where the icon_set_id matches the passed ID
|
|
$deleted_rows = $wpdb->delete(
|
|
$table_name,
|
|
array('icon_set_id' => $icon_set_id), // Condition to match rows by icon_set_id
|
|
array('%d') // Sanitize the value as an integer
|
|
);
|
|
|
|
// Check if rows were deleted successfully
|
|
if ($deleted_rows) {
|
|
wp_send_json_success(array('message' => 'Icon set uninstalled and icons removed from the database.'));
|
|
} else {
|
|
wp_send_json_error(array('message' => 'No icons found for the specified icon set ID.'));
|
|
}
|
|
}
|
|
|
|
add_action('wp_ajax_uninstall_icon_set', 'lcp_uninstall_icon_set');
|
|
|
|
/* Import Demo Posts */
|
|
function lcp_import_demo_posts() {
|
|
$json_data = file_get_contents(get_template_directory() . '/assets/json/demo-posts.json');
|
|
|
|
// Check if the JSON data is successfully fetched and decoded
|
|
if (empty($json_data)) {
|
|
return;
|
|
}
|
|
|
|
$posts = json_decode($json_data, true)['posts'];
|
|
|
|
if (empty($posts)) {
|
|
return;
|
|
}
|
|
|
|
// Arrays to store post IDs and media (thumbnail) IDs
|
|
$post_ids = [];
|
|
$media_ids = [];
|
|
|
|
foreach ($posts as $post) {
|
|
// Prepare post data
|
|
$post_data = array(
|
|
'post_title' => wp_strip_all_tags($post['title']),
|
|
'post_content' => $post['content'],
|
|
'post_excerpt' => isset($post['excerpt']) ? $post['excerpt'] : '',
|
|
'post_status' => isset($post['status']) ? $post['status'] : 'draft', // Default to 'draft' if no status
|
|
'post_date' => isset($post['date']) ? $post['date'] : current_time('mysql'),
|
|
'post_type' => 'post',
|
|
'post_author' => 1, // Change if you have specific user IDs
|
|
);
|
|
|
|
// Insert the post into the database
|
|
$post_id = wp_insert_post($post_data);
|
|
|
|
// If there was an issue inserting the post, skip this one
|
|
if (is_wp_error($post_id)) {
|
|
continue;
|
|
}
|
|
|
|
// Store the post ID in the array
|
|
$post_ids[] = $post_id;
|
|
|
|
// Assign categories (if they exist)
|
|
if (!empty($post['category'])) {
|
|
$category = term_exists($post['category'], 'category');
|
|
if ($category) {
|
|
wp_set_post_terms($post_id, array($category['term_id']), 'category');
|
|
} else {
|
|
// If category doesn't exist, create it
|
|
$category_id = wp_create_term($post['category'], 'category');
|
|
wp_set_post_terms($post_id, array($category_id['term_id']), 'category');
|
|
}
|
|
}
|
|
|
|
// Assign tags (if they exist)
|
|
if (!empty($post['tags'])) {
|
|
wp_set_post_terms($post_id, $post['tags'], 'post_tag');
|
|
}
|
|
|
|
// Handle thumbnail (featured image)
|
|
if (!empty($post['thumbnail'])) {
|
|
$thumbnail_url = get_template_directory_uri() . '/assets/img/demo-post-thumbnails/' . $post['thumbnail'];
|
|
|
|
// Download the image and add it to the media library
|
|
$thumbnail_id = media_handle_sideload(
|
|
array(
|
|
'name' => basename($thumbnail_url),
|
|
'tmp_name' => download_url($thumbnail_url)
|
|
),
|
|
$post_id
|
|
);
|
|
|
|
// If the image was uploaded successfully, set it as the post's featured image
|
|
if (!is_wp_error($thumbnail_id)) {
|
|
set_post_thumbnail($post_id, $thumbnail_id);
|
|
// Store the media ID in the array
|
|
$media_ids[] = $thumbnail_id;
|
|
}
|
|
}
|
|
|
|
// You can add additional meta fields if necessary
|
|
// Example:
|
|
// update_post_meta($post_id, 'some_meta_key', 'some_value');
|
|
}
|
|
|
|
// After all posts are imported, update the 'lcp_demo_posts' option
|
|
$demo_posts_data = array(
|
|
'post_ids' => $post_ids,
|
|
'media_ids' => $media_ids,
|
|
);
|
|
update_option('lcp_demo_posts', $demo_posts_data);
|
|
|
|
// Optionally, you can log the post and media IDs
|
|
// var_dump($post_ids, $media_ids); // Uncomment this line if you need to inspect the result
|
|
}
|
|
|
|
|
|
/* Delete the Demo Posts */
|
|
// Get the lcp_demo_posts option and delete all the posts from there
|
|
function lcp_delete_demo_posts() {
|
|
// Get the lcp_demo_posts option
|
|
$demo_posts_data = get_option('lcp_demo_posts');
|
|
|
|
// Check if the option exists and contains data
|
|
if (!empty($demo_posts_data) && isset($demo_posts_data['post_ids']) && isset($demo_posts_data['media_ids'])) {
|
|
// Loop through and delete posts
|
|
foreach ($demo_posts_data['post_ids'] as $post_id) {
|
|
// Delete post, force delete if necessary (set true for delete permanently)
|
|
wp_delete_post($post_id, true); // true will permanently delete
|
|
}
|
|
|
|
// Loop through and delete media (attachments)
|
|
foreach ($demo_posts_data['media_ids'] as $media_id) {
|
|
// Delete attachment (media file)
|
|
wp_delete_attachment($media_id, true); // true will permanently delete
|
|
}
|
|
|
|
// After deletion, remove the option from wp_options table
|
|
delete_option('lcp_demo_posts');
|
|
|
|
// Optionally, you can log the deletion for confirmation
|
|
// error_log('Demo posts and media have been deleted.');
|
|
} else {
|
|
// If the option doesn't exist, or it's empty
|
|
error_log('No demo posts data found or already deleted.');
|
|
}
|
|
}
|
|
|
|
|
|
/* Localize */
|
|
add_action('wp_ajax_lcp_import_demo_posts', 'lcp_import_demo_posts_ajax_handler');
|
|
|
|
// Define the function to handle the AJAX request
|
|
function lcp_import_demo_posts_ajax_handler() {
|
|
// Check for permissions (optional: can be used to ensure only admins can trigger this)
|
|
if (!current_user_can('manage_options')) {
|
|
wp_send_json_error('You do not have sufficient permissions to perform this action.');
|
|
}
|
|
|
|
// Call the existing function that imports the demo posts
|
|
lcp_import_demo_posts();
|
|
|
|
// Send a success response back to the browser
|
|
wp_send_json_success('Demo posts imported successfully.');
|
|
}
|
|
|
|
add_action('wp_ajax_lcp_delete_demo_posts', 'lcp_delete_demo_posts_ajax_handler');
|
|
|
|
// Define the function to handle the delete demo posts AJAX request
|
|
function lcp_delete_demo_posts_ajax_handler() {
|
|
// Verify nonce for security
|
|
if (!isset($_POST['lcp_import_nonce']) || !wp_verify_nonce($_POST['lcp_import_nonce'], 'lcp_import_demo_posts_nonce')) {
|
|
wp_send_json_error('Invalid nonce');
|
|
}
|
|
|
|
// Check if the current user has permissions to manage options
|
|
if (!current_user_can('manage_options')) {
|
|
wp_send_json_error('You do not have sufficient permissions to perform this action.');
|
|
}
|
|
|
|
// Call the function that deletes the demo posts
|
|
lcp_delete_demo_posts();
|
|
|
|
// Send a success response back to the browser
|
|
wp_send_json_success('Demo posts deleted successfully.');
|
|
}
|
|
|
|
|
|
|
|
// Set a visited post cookies
|
|
// Hooked into send_headers via wp-hooks.php
|
|
|
|
function lcp_set_visited_posts_cookie() {
|
|
// Only track posts on single post pages
|
|
if (is_single()) {
|
|
// Get the current post's ID and post type
|
|
$current_post_id = get_the_ID();
|
|
$post_type = get_post_type();
|
|
$visit_time = time(); // Get the current time as a Unix timestamp
|
|
|
|
// Check if the cookie exists
|
|
if (isset($_COOKIE['lcp_visited_posts'])) {
|
|
// Decode the cookie's JSON value
|
|
$visited_posts = json_decode(stripslashes($_COOKIE['lcp_visited_posts']), true);
|
|
|
|
// Check if decoding was successful and if the format is correct
|
|
if (json_last_error() !== JSON_ERROR_NONE || !is_array($visited_posts)) {
|
|
// If the cookie is not valid, delete the cookie and start over
|
|
setcookie('lcp_visited_posts', '', time() - 3600, '/'); // Expire the cookie
|
|
$visited_posts = []; // Initialize an empty array
|
|
}
|
|
} else {
|
|
// Initialize an empty array if the cookie doesn't exist
|
|
$visited_posts = [];
|
|
}
|
|
|
|
// If the post type is not already in the cookie, initialize it as an empty array
|
|
if (!isset($visited_posts[$post_type])) {
|
|
$visited_posts[$post_type] = [];
|
|
}
|
|
|
|
// Add the current post ID and the visit timestamp as an array entry
|
|
// Ensure that the post ID isn't already added for this post type
|
|
$found = false;
|
|
foreach ($visited_posts[$post_type] as &$post) {
|
|
if (array_key_exists($current_post_id, $post)) {
|
|
$post[$current_post_id] = $visit_time; // Update the timestamp if post already exists
|
|
$found = true;
|
|
break;
|
|
}
|
|
}
|
|
|
|
// If post wasn't found, add it as a new entry
|
|
if (!$found) {
|
|
$visited_posts[$post_type][] = [$current_post_id => $visit_time];
|
|
}
|
|
|
|
// Encode the updated visited posts array to JSON
|
|
$cookie_value = json_encode($visited_posts);
|
|
|
|
// Set the cookie with a 30-day expiration time (this must be done before any output)
|
|
setcookie('lcp_visited_posts', $cookie_value, time() + (30 * 24 * 60 * 60), '/'); // '/' makes the cookie available across the whole site
|
|
}
|
|
}
|
|
|
|
|
|
/* CUSTOM IMAGE SIZES */
|
|
function lcp_update_image_sizes() {
|
|
// Verify nonce for security
|
|
if (!isset($_POST['nonce']) || !wp_verify_nonce($_POST['nonce'], 'custom_image_sizes_nonce')) {
|
|
wp_send_json_error(array('message' => 'Nonce validation failed.'));
|
|
return;
|
|
}
|
|
|
|
// Check if image_sizes data is provided
|
|
if (isset($_POST['image_sizes'])) {
|
|
$image_sizes = json_decode(stripslashes($_POST['image_sizes']), true); // Decode JSON data
|
|
|
|
// Make sure that the image_sizes data is valid
|
|
if (!is_array($image_sizes)) {
|
|
wp_send_json_error(array('message' => 'Invalid image sizes data.'));
|
|
return;
|
|
}
|
|
|
|
// Process the data (e.g., update options)
|
|
update_option('lcp_image_sizes', $image_sizes);
|
|
|
|
// Return success message
|
|
wp_send_json_success(array('message' => 'Image sizes updated successfully.'));
|
|
} else {
|
|
wp_send_json_error(array('message' => 'No image sizes data received.'));
|
|
}
|
|
}
|
|
|
|
add_action('wp_ajax_update_lcp_theme_settings', 'lcp_update_image_sizes');
|
|
add_action('wp_ajax_nopriv_update_lcp_theme_settings', 'lcp_update_image_sizes');
|
|
|
|
function lcp_register_custom_image_sizes() {
|
|
// Retrieve the 'lcp_image_sizes' option, which is already unserialized by WordPress
|
|
$custom_image_sizes = get_option('lcp_image_sizes');
|
|
|
|
// Check if the option exists and is an array (because WordPress auto-unserializes the data)
|
|
if ($custom_image_sizes && is_array($custom_image_sizes)) {
|
|
// Loop through the array and register each image size
|
|
foreach ($custom_image_sizes as $size) {
|
|
// Ensure the size has the correct keys and valid values
|
|
if (isset($size['name'], $size['width'], $size['height'], $size['crop']) && !empty($size['name'])) {
|
|
// Sanitize the name, but ensure it's not just a number like '1'
|
|
$name = sanitize_key($size['name']);
|
|
$width = (int) $size['width']; // Cast to integer
|
|
$height = (int) $size['height']; // Cast to integer
|
|
$crop = (bool) $size['crop']; // Convert to boolean
|
|
|
|
// Register the custom image size
|
|
add_image_size($name, $width, $height, $crop);
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
|
|
// Hook into WordPress to register custom sizes
|
|
add_action('after_setup_theme', 'lcp_register_custom_image_sizes');
|
|
|
|
|
|
/* CUSTOM POST TYPES */
|
|
|
|
|
|
// Register the post meta field for the gallery
|
|
function to_register_meta_fields() {
|
|
register_post_meta('post', 'lcp_post_gallery', [
|
|
'type' => 'array',
|
|
'description' => 'Custom post gallery',
|
|
'single' => true,
|
|
'show_in_rest' => true,
|
|
]);
|
|
}
|
|
add_action('init', 'to_register_meta_fields');
|
|
|
|
// Add meta box for the gallery
|
|
function add_lcp_gallery_meta_box() {
|
|
add_meta_box(
|
|
'lcp_gallery_meta_box',
|
|
__('Post Gallery', 'textdomain'),
|
|
'render_lcp_gallery_meta_box',
|
|
'post',
|
|
'normal',
|
|
'high'
|
|
);
|
|
}
|
|
add_action('add_meta_boxes', 'add_lcp_gallery_meta_box');
|
|
|
|
// Render the meta box
|
|
function render_lcp_gallery_meta_box($post) {
|
|
// Add nonce for security
|
|
wp_nonce_field('lcp_gallery_meta_box', 'lcp_gallery_meta_box_nonce');
|
|
|
|
// Get existing gallery items
|
|
$gallery_items = get_post_meta($post->ID, 'lcp_gallery', true);
|
|
if (!is_array($gallery_items)) {
|
|
$gallery_items = array();
|
|
}
|
|
?>
|
|
<style>
|
|
#lcp-gallery-list li {
|
|
cursor: move;
|
|
padding: 10px;
|
|
margin-bottom: 10px;
|
|
background: #fff;
|
|
border: 1px solid #ddd;
|
|
position: relative;
|
|
}
|
|
#lcp-gallery-list li.dragging {
|
|
opacity: 0.5;
|
|
border: 2px dashed #999;
|
|
}
|
|
.drag-handle {
|
|
cursor: move;
|
|
padding: 5px;
|
|
margin-right: 10px;
|
|
color: #999;
|
|
}
|
|
#lcp-media-source-selector {
|
|
margin-bottom: 15px;
|
|
}
|
|
.gallery-item-fields {
|
|
margin-top: 10px;
|
|
}
|
|
.gallery-item-fields input[type="text"],
|
|
.gallery-item-fields textarea {
|
|
width: 100%;
|
|
margin-bottom: 5px;
|
|
}
|
|
.gallery-item-fields label {
|
|
display: block;
|
|
margin-top: 5px;
|
|
font-weight: bold;
|
|
}
|
|
.color-picker-wrapper {
|
|
display: flex;
|
|
align-items: center;
|
|
gap: 10px;
|
|
margin-top: 5px;
|
|
}
|
|
.color-picker-wrapper input[type="color"] {
|
|
padding: 0;
|
|
width: 50px;
|
|
height: 30px;
|
|
}
|
|
</style>
|
|
<div id="lcp-gallery-container">
|
|
<div id="lcp-media-source-selector">
|
|
<select id="lcp-media-source">
|
|
<option value="media_library">Media Library</option>
|
|
<option value="youtube">YouTube</option>
|
|
<option value="vimeo">Vimeo</option>
|
|
</select>
|
|
<button type="button" class="button" id="add-to-gallery">Add Media</button>
|
|
</div>
|
|
<ul id="lcp-gallery-list">
|
|
<?php
|
|
foreach ($gallery_items as $item) {
|
|
$media_source = isset($item['media_source']) ? $item['media_source'] : '';
|
|
$media_id = isset($item['media_id']) ? $item['media_id'] : '';
|
|
$url = isset($item['url']) ? $item['url'] : '';
|
|
$title = isset($item['title']) ? $item['title'] : '';
|
|
$caption = isset($item['caption']) ? $item['caption'] : '';
|
|
$background_color = isset($item['background_color']) ? $item['background_color'] : '';
|
|
|
|
echo '<li draggable="true" style="background-color: ' . esc_attr($background_color) . ';">';
|
|
echo '<span class="drag-handle dashicons dashicons-menu"></span>';
|
|
echo '<input type="hidden" name="lcp_gallery[]" value="' . esc_attr(json_encode($item)) . '">';
|
|
|
|
if ($media_source === 'media_library' && $media_id) {
|
|
$image = wp_get_attachment_image_src($media_id, 'thumbnail');
|
|
if ($image) {
|
|
echo '<img src="' . esc_url($image[0]) . '" alt="" style="max-width: 150px; height: auto;">';
|
|
}
|
|
} elseif ($media_source === 'youtube' && $url) {
|
|
echo '<div class="youtube-thumbnail" style="width: 150px; height: 150px; background: #f0f0f0; display: flex; align-items: center; justify-content: center;">';
|
|
echo '<span class="dashicons dashicons-youtube"></span>';
|
|
echo '</div>';
|
|
}
|
|
|
|
// Add fields for title, caption, and background color
|
|
echo '<div class="gallery-item-fields">';
|
|
echo '<label>Title</label>';
|
|
echo '<input type="text" class="gallery-item-title" value="' . esc_attr($title) . '" placeholder="Enter title">';
|
|
|
|
echo '<label>Caption</label>';
|
|
echo '<textarea class="gallery-item-caption" rows="3" placeholder="Enter caption">' . esc_textarea($caption) . '</textarea>';
|
|
|
|
echo '<label>Background Color</label>';
|
|
echo '<div class="color-picker-wrapper">';
|
|
echo '<input type="color" class="gallery-item-bgcolor" value="' . esc_attr($background_color) . '">';
|
|
echo '<button type="button" class="button update-bgcolor">Update Background</button>';
|
|
echo '</div>';
|
|
echo '</div>';
|
|
|
|
echo '<button type="button" class="button remove-gallery-item">Remove</button>';
|
|
echo '</li>';
|
|
}
|
|
?>
|
|
</ul>
|
|
</div>
|
|
|
|
<script>
|
|
document.addEventListener('DOMContentLoaded', function() {
|
|
// Initialize gallery items array from PHP
|
|
let galleryItems = <?php echo json_encode($gallery_items); ?>;
|
|
console.log('Initial gallery items:', galleryItems);
|
|
|
|
// Function to update hidden input values and maintain state
|
|
function updateHiddenInputs() {
|
|
const list = document.querySelector('#lcp-gallery-list');
|
|
list.innerHTML = ''; // Clear the list
|
|
|
|
console.log('Updating gallery items:', galleryItems);
|
|
|
|
// Rebuild the list with current items
|
|
galleryItems.forEach((item, index) => {
|
|
const li = document.createElement('li');
|
|
li.draggable = true;
|
|
if (item.background_color) {
|
|
li.style.backgroundColor = item.background_color;
|
|
}
|
|
|
|
// Add drag handle
|
|
const dragHandle = document.createElement('span');
|
|
dragHandle.className = 'drag-handle dashicons dashicons-menu';
|
|
li.appendChild(dragHandle);
|
|
|
|
// Add hidden input with item data
|
|
const input = document.createElement('input');
|
|
input.type = 'hidden';
|
|
input.name = 'lcp_gallery[]';
|
|
input.value = JSON.stringify(item);
|
|
li.appendChild(input);
|
|
|
|
// Add thumbnail
|
|
if (item.media_source === 'media_library' && item.media_id) {
|
|
wp.media.attachment(item.media_id).fetch().then(function() {
|
|
const img = document.createElement('img');
|
|
img.src = wp.media.attachment(item.media_id).get('url');
|
|
img.style = 'max-width: 150px; height: auto;';
|
|
li.appendChild(img);
|
|
});
|
|
} else if (item.media_source === 'youtube' && item.url) {
|
|
const div = document.createElement('div');
|
|
div.className = 'youtube-thumbnail';
|
|
div.style = 'width: 150px; height: 150px; background: #f0f0f0; display: flex; align-items: center; justify-content: center;';
|
|
div.innerHTML = '<span class="dashicons dashicons-youtube"></span>';
|
|
li.appendChild(div);
|
|
}
|
|
|
|
// Add fields container
|
|
const fields = document.createElement('div');
|
|
fields.className = 'gallery-item-fields';
|
|
|
|
// Title field
|
|
const titleLabel = document.createElement('label');
|
|
titleLabel.textContent = 'Title';
|
|
fields.appendChild(titleLabel);
|
|
|
|
const titleInput = document.createElement('input');
|
|
titleInput.type = 'text';
|
|
titleInput.className = 'gallery-item-title';
|
|
titleInput.value = item.title || '';
|
|
titleInput.placeholder = 'Enter title';
|
|
titleInput.addEventListener('input', () => {
|
|
item.title = titleInput.value;
|
|
updateItemData(index, item);
|
|
});
|
|
fields.appendChild(titleInput);
|
|
|
|
// Caption field
|
|
const captionLabel = document.createElement('label');
|
|
captionLabel.textContent = 'Caption';
|
|
fields.appendChild(captionLabel);
|
|
|
|
const captionInput = document.createElement('textarea');
|
|
captionInput.className = 'gallery-item-caption';
|
|
captionInput.rows = 3;
|
|
captionInput.value = item.caption || '';
|
|
captionInput.placeholder = 'Enter caption';
|
|
captionInput.addEventListener('input', () => {
|
|
item.caption = captionInput.value;
|
|
updateItemData(index, item);
|
|
});
|
|
fields.appendChild(captionInput);
|
|
|
|
// Background color field
|
|
const colorLabel = document.createElement('label');
|
|
colorLabel.textContent = 'Background Color';
|
|
fields.appendChild(colorLabel);
|
|
|
|
const colorWrapper = document.createElement('div');
|
|
colorWrapper.className = 'color-picker-wrapper';
|
|
|
|
const colorInput = document.createElement('input');
|
|
colorInput.type = 'color';
|
|
colorInput.className = 'gallery-item-bgcolor';
|
|
colorInput.value = item.background_color || '#ffffff';
|
|
|
|
const updateColorBtn = document.createElement('button');
|
|
updateColorBtn.type = 'button';
|
|
updateColorBtn.className = 'button update-bgcolor';
|
|
updateColorBtn.textContent = 'Update Background';
|
|
updateColorBtn.addEventListener('click', () => {
|
|
const newColor = colorInput.value;
|
|
item.background_color = newColor;
|
|
li.style.backgroundColor = newColor;
|
|
updateItemData(index, item);
|
|
console.log('Color updated for item', index, ':', item);
|
|
});
|
|
|
|
colorInput.addEventListener('input', () => {
|
|
// Preview the color as user picks
|
|
li.style.backgroundColor = colorInput.value;
|
|
});
|
|
|
|
colorWrapper.appendChild(colorInput);
|
|
colorWrapper.appendChild(updateColorBtn);
|
|
fields.appendChild(colorWrapper);
|
|
|
|
li.appendChild(fields);
|
|
|
|
// Add remove button
|
|
const removeBtn = document.createElement('button');
|
|
removeBtn.type = 'button';
|
|
removeBtn.className = 'button remove-gallery-item';
|
|
removeBtn.textContent = 'Remove';
|
|
removeBtn.onclick = function() {
|
|
galleryItems.splice(index, 1);
|
|
console.log('Removed item at index', index, '. New gallery items:', galleryItems);
|
|
updateHiddenInputs();
|
|
};
|
|
li.appendChild(removeBtn);
|
|
|
|
// Add drag and drop event listeners
|
|
li.addEventListener('dragstart', handleDragStart);
|
|
li.addEventListener('dragend', handleDragEnd);
|
|
li.addEventListener('dragover', handleDragOver);
|
|
li.addEventListener('drop', handleDrop);
|
|
|
|
list.appendChild(li);
|
|
});
|
|
}
|
|
|
|
// Function to update a specific item's data
|
|
function updateItemData(index, item) {
|
|
galleryItems[index] = item;
|
|
const input = document.querySelector(`#lcp-gallery-list li:nth-child(${index + 1}) input[name^="lcp_gallery"]`);
|
|
if (input) {
|
|
input.value = JSON.stringify(item);
|
|
console.log('Updated item at index', index, ':', item);
|
|
console.log('Current gallery items:', galleryItems);
|
|
}
|
|
}
|
|
|
|
// Initialize the list with existing items
|
|
if (galleryItems.length > 0) {
|
|
console.log('Initializing gallery with existing items:', galleryItems);
|
|
updateHiddenInputs();
|
|
}
|
|
|
|
// Handle drag and drop
|
|
let draggedItem = null;
|
|
let draggedIndex = null;
|
|
|
|
function handleDragStart(e) {
|
|
draggedItem = this;
|
|
draggedIndex = Array.from(draggedItem.parentNode.children).indexOf(draggedItem);
|
|
this.classList.add('dragging');
|
|
e.dataTransfer.effectAllowed = 'move';
|
|
console.log('Started dragging item at index:', draggedIndex);
|
|
}
|
|
|
|
function handleDragEnd(e) {
|
|
this.classList.remove('dragging');
|
|
draggedItem = null;
|
|
draggedIndex = null;
|
|
}
|
|
|
|
function handleDragOver(e) {
|
|
e.preventDefault();
|
|
e.dataTransfer.dropEffect = 'move';
|
|
}
|
|
|
|
function handleDrop(e) {
|
|
e.preventDefault();
|
|
if (draggedItem === this) return;
|
|
|
|
const droppedIndex = Array.from(this.parentNode.children).indexOf(this);
|
|
console.log('Dropping item from index', draggedIndex, 'to index', droppedIndex);
|
|
|
|
// Reorder galleryItems array
|
|
const [movedItem] = galleryItems.splice(draggedIndex, 1);
|
|
galleryItems.splice(droppedIndex, 0, movedItem);
|
|
|
|
console.log('Reordered gallery items:', galleryItems);
|
|
updateHiddenInputs();
|
|
}
|
|
|
|
// Initialize the media frame
|
|
let mediaFrame;
|
|
document.getElementById('add-to-gallery').addEventListener('click', function(e) {
|
|
e.preventDefault();
|
|
const source = document.getElementById('lcp-media-source').value;
|
|
|
|
if (source === 'media_library') {
|
|
if (mediaFrame) {
|
|
mediaFrame.open();
|
|
return;
|
|
}
|
|
|
|
mediaFrame = wp.media({
|
|
title: 'Select Media',
|
|
button: {
|
|
text: 'Add to Gallery'
|
|
},
|
|
multiple: false
|
|
});
|
|
|
|
mediaFrame.on('select', function() {
|
|
const attachment = mediaFrame.state().get('selection').first().toJSON();
|
|
const item = {
|
|
media_source: 'media_library',
|
|
media_id: attachment.id,
|
|
title: '',
|
|
caption: '',
|
|
background_color: ''
|
|
};
|
|
galleryItems.push(item);
|
|
console.log('Added new media library item:', item);
|
|
console.log('Current gallery items:', galleryItems);
|
|
updateHiddenInputs();
|
|
});
|
|
|
|
mediaFrame.open();
|
|
} else {
|
|
const url = prompt('Enter ' + source + ' URL:');
|
|
if (url) {
|
|
const item = {
|
|
media_source: source,
|
|
url: url,
|
|
title: '',
|
|
caption: '',
|
|
background_color: ''
|
|
};
|
|
galleryItems.push(item);
|
|
console.log('Added new URL item:', item);
|
|
console.log('Current gallery items:', galleryItems);
|
|
updateHiddenInputs();
|
|
}
|
|
}
|
|
});
|
|
});
|
|
</script>
|
|
<?php
|
|
}
|
|
|
|
// Save the gallery meta data
|
|
function save_lcp_gallery_meta_box($post_id) {
|
|
// Check if our nonce is set
|
|
if (!isset($_POST['lcp_gallery_meta_box_nonce'])) {
|
|
return;
|
|
}
|
|
|
|
// Verify that the nonce is valid
|
|
if (!wp_verify_nonce($_POST['lcp_gallery_meta_box_nonce'], 'lcp_gallery_meta_box')) {
|
|
return;
|
|
}
|
|
|
|
// If this is an autosave, our form has not been submitted, so we don't want to do anything
|
|
if (defined('DOING_AUTOSAVE') && DOING_AUTOSAVE) {
|
|
return;
|
|
}
|
|
|
|
// Check the user's permissions
|
|
if (isset($_POST['post_type']) && 'page' == $_POST['post_type']) {
|
|
if (!current_user_can('edit_page', $post_id)) {
|
|
return;
|
|
}
|
|
} else {
|
|
if (!current_user_can('edit_post', $post_id)) {
|
|
return;
|
|
}
|
|
}
|
|
|
|
// Save the gallery data
|
|
if (isset($_POST['lcp_gallery'])) {
|
|
$gallery_items = array_map(function($item) {
|
|
return is_string($item) ? json_decode(wp_unslash($item), true) : $item;
|
|
}, $_POST['lcp_gallery']);
|
|
|
|
update_post_meta($post_id, 'lcp_gallery', $gallery_items);
|
|
} else {
|
|
delete_post_meta($post_id, 'lcp_gallery');
|
|
}
|
|
}
|
|
add_action('save_post', 'save_lcp_gallery_meta_box');
|
|
|
|
// Enqueue color picker
|
|
function lcp_gallery_admin_enqueue($hook) {
|
|
if ('post.php' != $hook && 'post-new.php' != $hook) {
|
|
return;
|
|
}
|
|
wp_enqueue_style('wp-color-picker');
|
|
wp_enqueue_script('wp-color-picker');
|
|
}
|
|
add_action('admin_enqueue_scripts', 'lcp_gallery_admin_enqueue');
|
|
|
|
// Add AJAX handler for gallery updates
|
|
add_action('wp_ajax_update_gallery_meta', 'handle_gallery_meta_update');
|
|
add_action('wp_ajax_nopriv_update_gallery_meta', 'handle_gallery_meta_update');
|
|
|
|
function handle_gallery_meta_update() {
|
|
// Verify nonce for security
|
|
if (!current_user_can('edit_posts')) {
|
|
wp_send_json_error('Permission denied');
|
|
return;
|
|
}
|
|
|
|
$post_id = isset($_POST['post_id']) ? intval($_POST['post_id']) : 0;
|
|
$gallery_items = isset($_POST['gallery_items']) ? json_decode(stripslashes($_POST['gallery_items']), true) : array();
|
|
|
|
// Update the post meta
|
|
$updated = update_post_meta($post_id, 'lcp_gallery', $gallery_items);
|
|
|
|
if ($updated) {
|
|
wp_send_json_success(array('message' => 'Gallery updated successfully'));
|
|
} else {
|
|
wp_send_json_error(array('message' => 'Failed to update gallery'));
|
|
}
|
|
}
|