Plugin Directory

Changeset 3304136


Ignore:
Timestamp:
06/01/2025 04:07:28 AM (7 months ago)
Author:
daomapsieucap
Message:

Update to version 3.2.0 from GitHub

Location:
lipsum-dynamo
Files:
18 added
4 deleted
22 edited
1 copied

Legend:

Unmodified
Added
Removed
  • lipsum-dynamo/tags/3.2.0/assets/css/lipnamo-admin.css

    r2621502 r3304136  
    1212
    1313.lipnamo-preview {
    14     max-width:500px; height:200px;
     14    height:300px; max-width:800px;
    1515    background-color:#fff;border:#ccd0d4 solid 1px;
    1616    margin-bottom:20px;overflow-x:auto;
    1717}
    1818.lipnamo-preview .lipnamo-input__img {margin-bottom:10px;}
    19 .lipnamo-preview .lipnamo-preview__list {display:flex; flex-wrap:wrap;}
    20 .lipnamo-preview .lipnamo-preview__list {padding:0 10px;}
    21 .lipnamo-preview .lipnamo-preview__list li {width:25%;}
    22 .lipnamo-preview .lipnamo-preview__list li span {
    23     display:block; padding:10px; margin:5px;
    24     background:#eee; border:#d5d9dd solid 1px;
     19
     20.lipnamo-preview .lipnamo-preview-item.attachment {width:16.66%;}
     21.lipnamo-preview .lipnamo-preview-item.attachment img {max-height:100%; max-width:100%;}
     22
     23/* Loading state for preview items */
     24.lipnamo-preview-item.lipnamo-loading .lipnamo-preview-wrapper {
     25    opacity:0.5;
     26    pointer-events:none;
    2527}
    26 .lipnamo-preview .lipnamo-preview__list li img {
    27     height:auto; max-height:100%;
    28     width:auto; max-width:100%;
     28
     29.lipnamo-preview-item.lipnamo-loading .lipnamo-preview-wrapper::after {
     30    content:"";
     31    position:absolute;
     32    top:50%;
     33    left:50%;
     34    width:20px;
     35    height:20px;
     36    margin:-10px 0 0 -10px;
     37    border:2px solid #ccc;
     38    border-top-color:#0073aa;
     39    border-radius:50%;
     40    animation:lipnamo-spin 1s linear infinite;
     41}
     42
     43@keyframes lipnamo-spin {
     44    to { transform:rotate(360deg); }
     45}
     46
     47/* Empty state */
     48.lipnamo-preview__list:empty::after {
     49    content:"No images selected. Click 'Upload Images' to add some.";
     50    display:block;
     51    padding:20px;
     52    text-align:center;
     53    color:#666;
     54    font-style:italic;
    2955}
    3056
     
    3359 */
    3460
    35 .lipnamo-length-control input {margin:0 0 1em;}
     61.lipnamo-length-control input {margin:0 0 16px;}
    3662.lipnamo-length-control label, .lipnamo-length-control select {
    37     display:inline-block;min-width:10em;vertical-align:middle;
    38     margin:.35em 0 .75em !important;
     63    display:inline-block;min-width:160px;vertical-align:middle;
     64    margin:6px 0 12px !important;
    3965}
    4066
     
    4369 */
    4470
    45 .lipnamo-progress-wrapper {max-width:1000px;margin-bottom:20px;background-color:#fff; padding:15px 10px;}
    46 .lipnamo-progress {margin-bottom:5px;color:#000;background-color:#cecece;}
     71.lipnamo-progress-wrapper {
     72    max-width:1000px;
     73    margin-bottom:20px;
     74    background-color:#fff;
     75    padding:15px 10px;
     76    border:1px solid #c3c4c7;
     77    border-radius:4px;
     78}
     79
     80.lipnamo-progress {
     81    margin-bottom:5px;
     82    color:#1d2327;
     83    background-color:#dcdcde;
     84    border-radius:3px;
     85    overflow:hidden;
     86    height:20px;
     87}
     88
    4789.lipnamo-progress-bar {
    48     height:20px;padding:0.01em 0;background-color:#0073aa;
     90    height:20px;
     91    padding:1px 0;
     92    background-color:#2271b1;
     93    border-radius:2px;
     94    transition:width 0.3s ease;
    4995}
  • lipsum-dynamo/tags/3.2.0/assets/js/lipnamo-admin.js

    r2595116 r3304136  
    11jQuery(document).ready(function($){
     2    'use strict';
     3
     4    // Cache frequently used selectors
     5    const $thumbnailsField = $('#lipnamo-thumbnails');
     6
    27    /**
    3      * Upload field
     8     * Toggle preview visibility based on input value
    49     */
    5     // show hide preview
    610    $('.lipnamo-input__img input[type="text"]').on('change', function(){
    7         const preview = $(this).closest('fieldset').find('img');
    8         if(!$(this).val()){
    9             preview.hide();
    10         }else{
    11             preview.show();
    12         }
     11        const $preview = $(this).closest('fieldset').find('img');
     12        $preview.toggle(!!$(this).val());
    1313    });
    1414
    15     // preview
     15    /**
     16     * Media uploader functionality
     17     */
    1618    $('.lipnamo-upload').each(function(){
    17         const upload_element = $(this),
    18             preview = upload_element.closest('fieldset').find('.lipnamo-preview__list');
     19        const $uploadButton = $(this);
     20        const $preview = $uploadButton.closest('fieldset').find('.lipnamo-preview__list');
     21        let mediaUploader;
    1922
    20         let custom_uploader;
     23        $uploadButton.on('click', function(e){
     24            e.preventDefault();
    2125
    22         upload_element.click(function(e){
    23             e.preventDefault();
    24             //If the uploader object has already been created, reopen the dialog
    25             if(custom_uploader){
    26                 custom_uploader.open();
     26            // Reopen existing uploader
     27            if(mediaUploader){
     28                mediaUploader.open();
    2729                return;
    2830            }
    29             //Extend the wp.media object
    30             custom_uploader = wp.media.frames.file_frame = wp.media({
    31                 title: 'Choose Image',
    32                 button: {
    33                     text: 'Choose Image'
    34                 },
    35                 multiple: 'add'
    36             });
    37             //When a file is selected, grab the URL and set it as the text field's value
    38             custom_uploader.on('select', function(){
    39                 const attachment = custom_uploader.state().get('selection').toJSON(),
    40                     $thumbnails = $('#lipnamo-thumbnails');
    4131
    42                 let thumbnail_val = $thumbnails.val();
    43 
    44                 if(attachment){
    45                     for(let i = 0; i < attachment.length; i++){
    46                         thumbnail_val = $thumbnails.val();
    47                         if(thumbnail_val){
    48                             $thumbnails.val(thumbnail_val + ',' + attachment[i].id);
    49                             let thumbnail_array = thumbnail_val.split(",").map(Number);
    50                             if(!thumbnail_array.includes(attachment[i].id)){
    51                                 preview.append('<li><span><img src="' + attachment[i].url + '" /></span></li>');
    52                             }
    53                         }else{
    54                             $thumbnails.val(attachment[i].id);
    55                             preview.append('<li><span><img src="' + attachment[i].url + '" /></span></li>');
    56                         }
    57                     }
     32            // Create new media uploader
     33            mediaUploader = wp.media({
     34                title: 'Choose Images',
     35                button: {text: 'Choose Images'},
     36                multiple: 'add',
     37                library: {
     38                    type: 'image'
    5839                }
    5940            });
    60             //Show selected items when open media popup
    61             custom_uploader.on('open', function(){
    62                 const selection = custom_uploader.state().get('selection'),
    63                     ids_value = $('#lipnamo-thumbnails').val();
    6441
    65                 if(ids_value.length > 0){
    66                     var ids = ids_value.split(',');
     42            // Handle media selection
     43            mediaUploader.on('select', function(){
     44                const attachments = mediaUploader.state().get('selection').toJSON();
     45                lipnamoAddSelectedImages(attachments, $preview);
     46            });
    6747
    68                     ids.forEach(function(id){
    69                         let attachment = wp.media.attachment(id);
    70                         attachment.fetch();
    71                         selection.add(attachment ? [attachment] : []);
    72                     });
    73                 }
     48            // Pre-select existing images when opening
     49            mediaUploader.on('open', function(){
     50                lipnamoPreselectExistingImages(mediaUploader);
    7451            });
    75             //Open the uploader dialog
    76             custom_uploader.open();
     52
     53            mediaUploader.open();
    7754        });
    7855    });
     56
     57    /**
     58     * Remove thumbnail functionality
     59     */
     60    $(document).on('click', '.lipnamo-remove-thumbnail', function(e){
     61        e.preventDefault();
     62
     63        const imageId = parseInt($(this).data('lipnamo-id'));
     64        const $previewItem = $(this).closest('.lipnamo-preview-item');
     65
     66        lipnamoRemoveImageFromField(imageId);
     67        $previewItem.fadeOut(300, function(){
     68            $(this).remove();
     69        });
     70    });
     71
     72    /**
     73     * Add selected images to preview and update field
     74     */
     75    function lipnamoAddSelectedImages(attachments, $preview){
     76        if(!attachments?.length) return;
     77
     78        const currentIds = lipnamoGetCurrentImageIds();
     79        const newIds = [];
     80
     81        attachments.forEach((attachment, index) => {
     82            const imageId = parseInt(attachment.id);
     83
     84            // Skip if image already exists
     85            if(currentIds.includes(imageId)) return;
     86
     87            // Add to new IDs array
     88            newIds.push(imageId);
     89
     90            // Add to preview
     91            const altText = attachment.alt || `Image ${index + 1}`;
     92            $preview.append(lipnamoCreateThumbnailHTML(imageId, attachment.url, altText));
     93        });
     94
     95        // Update hidden field with combined IDs
     96        if(newIds.length){
     97            lipnamoUpdateThumbnailField([...currentIds, ...newIds]);
     98        }
     99    }
     100
     101    /**
     102     * Create thumbnail HTML
     103     */
     104    function lipnamoCreateThumbnailHTML(imageId, imageUrl, altText){
     105        return `
     106            <li class="lipnamo-preview-item attachment" data-lipnamo-id="${imageId}">
     107                <div class="attachment-preview">
     108                    <div class="thumbnail">
     109                        <div class="centered">
     110                            <img src="${imageUrl}" alt="${altText}" class="lipnamo-preview-image" />
     111                        </div>
     112                    </div>
     113                    <button type="button" class="lipnamo-remove-thumbnail button-link attachment-close media-modal-icon"
     114                            data-lipnamo-id="${imageId}" title="Remove image" aria-label="Remove image">
     115                        <span class="screen-reader-text">Remove</span>
     116                    </button>
     117                </div>
     118            </li>
     119        `;
     120    }
     121
     122    /**
     123     * Get current image IDs from hidden field
     124     */
     125    function lipnamoGetCurrentImageIds(){
     126        const value = $thumbnailsField.val().trim();
     127        return value ? value.split(',').map(id => parseInt(id.trim())).filter(id => !isNaN(id)) : [];
     128    }
     129
     130    /**
     131     * Update thumbnail field with new IDs
     132     */
     133    function lipnamoUpdateThumbnailField(imageIds){
     134        const uniqueIds = [...new Set(imageIds)].filter(id => !isNaN(id));
     135        $thumbnailsField.val(uniqueIds.length ? uniqueIds.join(',') : '');
     136    }
     137
     138    /**
     139     * Remove image ID from hidden field
     140     */
     141    function lipnamoRemoveImageFromField(imageId){
     142        const currentIds = lipnamoGetCurrentImageIds();
     143        const updatedIds = currentIds.filter(id => id !== imageId);
     144        lipnamoUpdateThumbnailField(updatedIds);
     145    }
     146
     147    /**
     148     * Pre-select existing images in media uploader
     149     */
     150    function lipnamoPreselectExistingImages(uploader){
     151        const imageIds = lipnamoGetCurrentImageIds();
     152        if(!imageIds.length) return;
     153
     154        const selection = uploader.state().get('selection');
     155
     156        imageIds.forEach(id => {
     157            const attachment = wp.media.attachment(id);
     158            attachment.fetch();
     159            selection.add(attachment);
     160        });
     161    }
    79162});
  • lipsum-dynamo/tags/3.2.0/assets/js/lipnamo-cleanup-items.js

    r2621502 r3304136  
    1 jQuery(document).ready(function($){
    2     const $wpbody = $("#wpbody"), $cleanupButton = $('.lipnamo-cleanup.button');
    3 
    4     // Update post total
    5     $('select[name="lipnamo_post_type"]').on('change', function(){
    6         const post_type = $('select[name="lipnamo_post_type"]').val();
    7 
    8         $wpbody.addClass("lipnamo-loading");
    9         $cleanupButton.addClass('disabled');
    10 
    11         $.ajax({
    12             url: lipnamo_items.ajax_url,
    13             type: 'POST',
    14             data: {
    15                 action: 'lipnamo_total_items',
    16                 lipnamo_ajax_nonce: lipnamo_items.ajax_nonce,
    17                 post_type: post_type
    18             },
    19             success: function(response){
    20                 let result = JSON.parse(response),
    21                     post_total = parseInt(result.post_total);
    22 
    23                 $('input[name="lipnamo_post_total"]').val(post_total);
    24 
    25                 $wpbody.removeClass("lipnamo-loading");
    26                 $cleanupButton.removeClass('disabled');
    27             }
    28         });
    29     });
    30 
    31     // AJAX Cleanup
    32     let ajaxIndex = 1;
    33 
    34     $cleanupButton.click(function(e){
    35         e.preventDefault();
    36         lipnamoCleanupItems();
    37     });
    38 
    39     function lipnamoCleanupItems(){
    40         const post_total = parseInt($('input[name="lipnamo_post_total"]').val()),
    41             post_type = $('select[name="lipnamo_post_type"]').val(),
    42             $progressBar = $('.lipnamo-progress-bar');
    43 
    44         $wpbody.addClass("lipnamo-loading");
    45         $(".lipnamo-progress-wrapper").show();
    46         $(this).addClass('disabled');
    47 
    48         if(ajaxIndex > post_total){
     1class LipnamoCleanupManager{
     2    constructor(){
     3        this.currentStep = 1;
     4        this.isRunning = false;
     5        this.config = {};
     6        this.elements = {};
     7
     8        this.init();
     9    }
     10
     11    init(){
     12        this.cacheElements();
     13        this.bindEvents();
     14    }
     15
     16    cacheElements(){
     17        this.elements = {
     18            wpBody: document.getElementById('wpbody'),
     19            cleanupButton: document.querySelector('.lipnamo-cleanup.button'),
     20            progressBar: document.querySelector('.lipnamo-progress-bar'),
     21            progressWrapper: document.querySelector('.lipnamo-progress-wrapper'),
     22            progressStep: document.querySelector('.lipnamo-progress-step'),
     23            progressTotal: document.querySelector('.lipnamo-progress-total'),
     24            progressText: document.querySelector('.lipnamo-progress-text'),
     25            stepInput: document.querySelector('input[name="lipnamo-cleanup__step"]'),
     26            // Form inputs
     27            postTotalInput: document.querySelector('input[name="lipnamo_post_total"]'),
     28            postTypeSelect: document.querySelector('select[name="lipnamo_post_type"]')
     29        };
     30    }
     31
     32    bindEvents(){
     33        if(this.elements.postTypeSelect){
     34            this.elements.postTypeSelect.addEventListener('change', () => {
     35                this.updatePostTotal();
     36            });
     37        }
     38
     39        if(this.elements.cleanupButton){
     40            this.elements.cleanupButton.addEventListener('click', (e) => {
     41                e.preventDefault();
     42                this.startCleanup();
     43            });
     44        }
     45    }
     46
     47    async updatePostTotal(){
     48        const postType = this.elements.postTypeSelect?.value || '';
     49
     50        this.showLoading();
     51        this.disableCleanupButton();
     52
     53        try{
     54            const formData = new FormData();
     55            formData.append('action', 'lipnamo_total_items');
     56            formData.append('lipnamo_ajax_nonce', lipnamo_items.ajax_nonce);
     57            formData.append('post_type', postType);
     58
     59            const response = await fetch(lipnamo_items.ajax_url, {
     60                method: 'POST',
     61                body: formData,
     62                credentials: 'same-origin'
     63            });
     64
     65            if(!response.ok){
     66                throw new Error(`HTTP error! status: ${response.status}`);
     67            }
     68
     69            const responseText = await response.text();
     70            const result = JSON.parse(responseText);
     71            const postTotal = parseInt(result.post_total) || 0;
     72
     73            if(this.elements.postTotalInput){
     74                this.elements.postTotalInput.value = postTotal;
     75            }
     76
     77        }catch(error){
     78            console.error('LipnamoCleanupManager: Error updating post total', error);
     79        }finally{
     80            this.hideLoading();
     81            this.enableCleanupButton();
     82        }
     83    }
     84
     85    startCleanup(){
     86        if(this.isRunning) return;
     87
     88        this.config = this.getCleanupConfig();
     89        this.currentStep = 1;
     90        this.isRunning = true;
     91
     92        this.showProgress();
     93        if(this.elements.progressTotal){
     94            this.elements.progressTotal.textContent = this.config.postTotal;
     95        }
     96
     97        this.lipnamoCleanupItems();
     98    }
     99
     100    getCleanupConfig(){
     101        return {
     102            postTotal: parseInt(this.elements.postTotalInput?.value) || 0,
     103            postType: this.elements.postTypeSelect?.value || ''
     104        };
     105    }
     106
     107    showLoading(){
     108        if(this.elements.wpBody){
     109            this.elements.wpBody.classList.add('lipnamo-loading');
     110        }
     111    }
     112
     113    hideLoading(){
     114        if(this.elements.wpBody){
     115            this.elements.wpBody.classList.remove('lipnamo-loading');
     116        }
     117    }
     118
     119    showProgress(){
     120        this.showLoading();
     121        if(this.elements.progressWrapper){
     122            this.elements.progressWrapper.style.display = 'block';
     123        }
     124        this.disableCleanupButton();
     125    }
     126
     127    hideProgress(){
     128        this.hideLoading();
     129        this.enableCleanupButton();
     130        this.isRunning = false;
     131    }
     132
     133    disableCleanupButton(){
     134        if(this.elements.cleanupButton){
     135            this.elements.cleanupButton.classList.add('disabled');
     136        }
     137    }
     138
     139    enableCleanupButton(){
     140        if(this.elements.cleanupButton){
     141            this.elements.cleanupButton.classList.remove('disabled');
     142        }
     143    }
     144
     145    updateProgress(step, total){
     146        const percent = Math.min((step * 100) / total, 100);
     147
     148        if(this.elements.progressStep){
     149            this.elements.progressStep.textContent = step;
     150        }
     151        if(this.elements.stepInput){
     152            this.elements.stepInput.value = step;
     153        }
     154
     155        if(this.elements.progressBar){
     156            this.animateProgressBar(percent);
     157        }
     158    }
     159
     160    animateProgressBar(targetPercent){
     161        const progressBar = this.elements.progressBar;
     162        const currentWidth = parseFloat(progressBar.style.width) || 0;
     163        const targetWidth = targetPercent;
     164        const duration = 150;
     165        const startTime = performance.now();
     166
     167        const animate = (currentTime) => {
     168            const elapsed = currentTime - startTime;
     169            const progress = Math.min(elapsed / duration, 1);
     170
     171            // Easing function (ease-out)
     172            const easeOut = 1 - Math.pow(1 - progress, 3);
     173            const currentPercent = currentWidth + (targetWidth - currentWidth) * easeOut;
     174
     175            progressBar.style.width = `${currentPercent}%`;
     176
     177            if(progress < 1){
     178                requestAnimationFrame(animate);
     179            }
     180        };
     181
     182        requestAnimationFrame(animate);
     183    }
     184
     185    async lipnamoCleanupItems(){
     186        if(this.currentStep > this.config.postTotal){
     187            this.hideProgress();
    49188            return;
    50189        }
    51190
    52         // Update progress total
    53         $('.lipnamo-progress-total').text(post_total);
    54 
    55         // Deleting items
    56         $.ajax({
    57             url: lipnamo_items.ajax_url,
    58             type: 'POST',
    59             data: {
    60                 action: 'lipnamo_cleanup_items',
    61                 lipnamo_ajax_nonce: lipnamo_items.ajax_nonce,
    62                 post_total: post_total,
    63                 post_type: post_type,
    64                 post_step: ajaxIndex
    65             },
    66             success: function(response){
    67                 let result = JSON.parse(response),
    68                     step = parseInt(result.step),
    69                     percent = step * 100 / post_total;
    70 
    71                 $('input[name="lipnamo-cleanup__step"]').val(step);
    72 
    73                 if(step < post_total){
    74                     $('.lipnamo-progress-step').text(step);
    75                     $progressBar.animate({
    76                         width: percent + '%'
    77                     }, 150);
    78                 }else{
    79                     $progressBar.animate({
    80                         width: '100%'
    81                     }, 150);
    82                     $('.lipnamo-progress-text').text(result.message);
     191        try{
     192            const formData = new FormData();
     193            formData.append('action', 'lipnamo_cleanup_items');
     194            formData.append('lipnamo_ajax_nonce', lipnamo_items.ajax_nonce);
     195            formData.append('post_total', this.config.postTotal);
     196            formData.append('post_type', this.config.postType);
     197            formData.append('post_step', this.currentStep);
     198
     199            const response = await fetch(lipnamo_items.ajax_url, {
     200                method: 'POST',
     201                body: formData,
     202                credentials: 'same-origin'
     203            });
     204
     205            if(!response.ok){
     206                throw new Error(`HTTP error! status: ${response.status}`);
     207            }
     208
     209            const responseText = await response.text();
     210            await this.handleSuccess(responseText);
     211
     212        }catch(error){
     213            this.handleError(error);
     214        }
     215    }
     216
     217    async handleSuccess(responseText){
     218        try{
     219            const result = JSON.parse(responseText);
     220            const step = parseInt(result.step) || this.currentStep;
     221
     222            this.updateProgress(step, this.config.postTotal);
     223
     224            if(step >= this.config.postTotal){
     225                if(this.elements.progressText){
     226                    this.elements.progressText.textContent = result.message || 'Cleanup completed!';
    83227                }
    84 
    85                 //do your thing
    86                 ajaxIndex++;
    87                 //go to next iteration of the loop
    88                 lipnamoCleanupItems();
    89             }
    90         });
    91 
    92         $wpbody.removeClass("lipnamo-loading");
    93         $(this).removeClass('disabled');
    94     }
     228                this.hideProgress();
     229                return;
     230            }
     231
     232            this.currentStep = step + 1;
     233
     234            // Add small delay to prevent overwhelming the server
     235            setTimeout(() => {
     236                if(this.isRunning){
     237                    this.lipnamoCleanupItems();
     238                }
     239            }, 100);
     240
     241        }catch(error){
     242            console.error('LipnamoCleanupManager: Error parsing response', error);
     243            this.handleError(error);
     244        }
     245    }
     246
     247    handleError(error){
     248        console.error('LipnamoCleanupManager: Error', error);
     249        if(this.elements.progressText){
     250            this.elements.progressText.textContent = 'An error occurred during cleanup. Please try again.';
     251        }
     252        this.hideProgress();
     253    }
     254
     255    // Public methods for external access
     256    stop(){
     257        this.isRunning = false;
     258        this.hideProgress();
     259    }
     260
     261    reset(){
     262        this.stop();
     263        this.currentStep = 1;
     264        if(this.elements.progressBar){
     265            this.elements.progressBar.style.width = '0%';
     266        }
     267        if(this.elements.progressStep){
     268            this.elements.progressStep.textContent = '0';
     269        }
     270        if(this.elements.progressText){
     271            this.elements.progressText.textContent = '';
     272        }
     273        if(this.elements.stepInput){
     274            this.elements.stepInput.value = '';
     275        }
     276    }
     277
     278    getStatus(){
     279        return {
     280            isRunning: this.isRunning,
     281            currentStep: this.currentStep,
     282            totalSteps: this.config.postTotal,
     283            postType: this.config.postType
     284        };
     285    }
     286}
     287
     288document.addEventListener('DOMContentLoaded', function(){
     289    new LipnamoCleanupManager();
    95290});
  • lipsum-dynamo/tags/3.2.0/assets/js/lipnamo-generate-items.js

    r2621502 r3304136  
    11jQuery(document).ready(function($){
    2     let i = 1;
     2    let lipnamoCurrentStep = 1;
    33
    44    $('.lipnamo-generate').click(function(e){
     
    2626        $(this).addClass('disabled');
    2727
    28         if(i > post_total){
     28        // stop when current step is greater than total posts
     29        if(lipnamoCurrentStep > post_total){
    2930            return;
    3031        }
     
    4849                post_excerpt_length: post_excerpt_min + ',' + post_excerpt_max,
    4950                post_body_length: post_body_min + ',' + post_body_max,
    50                 post_step: i
     51                post_step: lipnamoCurrentStep
    5152            },
    5253            success: function(response){
     
    6970                }
    7071
    71                 //do your thing
    72                 i++;
    73                 //go to next iteration of the loop
     72                // increase step
     73                lipnamoCurrentStep++;
     74
     75                //continue generating items
    7476                lipnamoGenerateItems();
    7577            }
  • lipsum-dynamo/tags/3.2.0/changelog.txt

    r3117972 r3304136  
    11== Changelog ==
     2
     3= 3.2.0 =
     4*Release Date - 01 June 2025*
     5
     6* New: Add option to remove specific thumbnails.
     7* New: Add list format with a tag in post content.
     8* Changed: Inherit media style from WordPress core.
     9* Changed: Optimize code for better performance.
     10* Changed: Tested up to 6.8.1.
    211
    312= 3.1.0 =
  • lipsum-dynamo/tags/3.2.0/includes/cleanup.php

    r3117972 r3304136  
    2020   
    2121    public function lipnamo_cleanup_scripts($hook_suffix){
    22         if(strpos($hook_suffix, 'lipsum-dynamo') !== false){
    23             wp_enqueue_script('lipnamo-cleanup-items', LIPNAMO_ASSETS_URL . 'js/lipnamo-cleanup-items.js', ['jquery'], DUMMIE_VERSION, true);
     22        if(str_contains($hook_suffix, 'lipsum-dynamo')){
     23            wp_enqueue_script('lipnamo-cleanup-items', LIPNAMO_ASSETS_URL . 'js/lipnamo-cleanup-items' . LIPNAMO_CSSJS_SUFFIX . '.js', false, LIPNAMO_VERSION, true);
    2424            wp_localize_script('lipnamo-cleanup-items', 'lipnamo_items',
    2525                [
     
    4343       
    4444        // Get AJAX data
    45         $post_total = intval(lipnamo_array_key_exists('post_total', $_POST, 10));
     45        $post_total = (int) lipnamo_array_key_exists('post_total', $_POST, 10);
    4646        $post_type  = sanitize_text_field(lipnamo_array_key_exists('post_type', $_POST, 'any'));
    47         $post_step  = intval(lipnamo_array_key_exists('post_step', $_POST));
     47        $post_step  = (int) lipnamo_array_key_exists('post_step', $_POST);
    4848       
    4949        // Exit if invalid post type
     
    6969            if($posts){
    7070                foreach($posts as $post){
    71                     $post_id = intval($post->post_id);
     71                    $post_id = (int) $post->post_id;
    7272                    if(get_post_status($post_id)){
    7373                        wp_delete_post($post_id, true);
     
    9494       
    9595        // Send output as JSON for processing via AJAX.
    96         echo json_encode($result);
     96        echo json_encode($result, JSON_THROW_ON_ERROR);
    9797        exit;
    9898    }
     
    124124       
    125125        $table_name = $wpdb->prefix . 'lipnamo';
    126         if($post_type == "any"){
     126        if($post_type === "any"){
    127127            $mysql_query = "SELECT * FROM $table_name";
    128128        }else{
     
    137137       
    138138        // Send output as JSON for processing via AJAX.
    139         echo json_encode($result);
     139        echo json_encode($result, JSON_THROW_ON_ERROR);
    140140        exit;
    141141    }
  • lipsum-dynamo/tags/3.2.0/includes/generate-items.php

    r3117972 r3304136  
    1919   
    2020    public function lipnamo_generate_scripts($hook_suffix){
    21         if(strpos($hook_suffix, 'lipsum-dynamo') !== false){
    22             wp_enqueue_script('lipnamo-generate-items', LIPNAMO_ASSETS_URL . 'js/lipnamo-generate-items.js', ['jquery'], DUMMIE_VERSION, true);
     21        if(str_contains($hook_suffix, 'lipsum-dynamo')){
     22            wp_enqueue_script('lipnamo-generate-items', LIPNAMO_ASSETS_URL . 'js/lipnamo-generate-items.js', false, LIPNAMO_VERSION, true);
    2323            wp_localize_script('lipnamo-generate-items', 'lipnamo_items',
    2424                [
     
    4242       
    4343        // Get AJAX data
    44         $post_total          = intval(lipnamo_array_key_exists('post_total', $_POST, 10));
     44        $post_total          = (int) lipnamo_array_key_exists('post_total', $_POST, 10);
    4545        $post_type           = sanitize_text_field(lipnamo_array_key_exists('post_type', $_POST, 'post'));
    46         $post_author         = intval(lipnamo_array_key_exists('post_author', $_POST));
     46        $post_author         = (int) lipnamo_array_key_exists('post_author', $_POST);
    4747        $post_status         = sanitize_text_field(lipnamo_array_key_exists('post_status', $_POST, 'publish'));
    4848        $post_thumbnails     = sanitize_text_field(lipnamo_array_key_exists('post_thumbnails', $_POST));
     
    5050        $post_excerpt_length = sanitize_text_field(lipnamo_array_key_exists('post_excerpt_length', $_POST));
    5151        $post_body_length    = sanitize_text_field(lipnamo_array_key_exists('post_body_length', $_POST));
    52         $post_step           = intval(lipnamo_array_key_exists('post_step', $_POST));
     52        $post_step           = (int) lipnamo_array_key_exists('post_step', $_POST);
    5353       
    5454        // Exit if invalid post type
     
    6262        if($post_title_length){
    6363            $post_title_array = explode(',', $post_title_length);
    64             $post_title_min   = intval($post_title_array[0]);
    65             $post_title_max   = intval($post_title_array[1]);
     64            $post_title_min   = (int) $post_title_array[0];
     65            $post_title_max   = (int) $post_title_array[1];
    6666        }
    6767        $post_excerpt_min = $post_excerpt_max = 1;
    6868        if($post_excerpt_length){
    6969            $post_excerpt_array = explode(',', $post_excerpt_length);
    70             $post_excerpt_min   = intval($post_excerpt_array[0]);
    71             $post_excerpt_max   = intval($post_excerpt_array[1]);
     70            $post_excerpt_min   = (int) $post_excerpt_array[0];
     71            $post_excerpt_max   = (int) $post_excerpt_array[1];
    7272        }
    7373        $post_body_min = $post_body_max = 1;
    7474        if($post_body_length){
    7575            $post_body_array = explode(',', $post_body_length);
    76             $post_body_min   = intval($post_body_array[0]);
    77             $post_body_max   = intval($post_body_array[1]);
     76            $post_body_min   = (int) $post_body_array[0];
     77            $post_body_max   = (int) $post_body_array[1];
    7878        }
    7979       
     
    9292            }
    9393           
     94            // prevent lorem ipsum from generating the same word twice in a row
    9495            if($post_step > 1){
    9596                $generator->word();
    9697            }
     98           
     99            // variables
    97100            $post_title   = ucfirst($generator->words($title_words));
    98101            $post_excerpt = $generator->sentences($excerpt_sentences);
    99             $post_content = $generator->paragraphs($content_paragraphs);
     102            $post_content = '<ul>';
     103            for($list_index = 0;$list_index < 3;$list_index ++){
     104                $list_title   = $generator->words(5);
     105                $post_content .= '<li><a href="#" title="' . $list_title . '">' . $list_title . '</a></li>';
     106               
     107            }
     108            $post_content .= '</ul>';
     109            $post_content .= $generator->paragraphs($content_paragraphs - 1);
    100110           
    101111            // Create post
  • lipsum-dynamo/tags/3.2.0/includes/setting/general.php

    r3117972 r3304136  
    174174        ?>
    175175        <fieldset class="lipnamo-input__img">
    176             <div class="lipnamo-preview">
    177                 <ul class="lipnamo-preview__list"></ul>
     176            <div class="lipnamo-preview attachments-wrapper">
     177                <ul class="attachments lipnamo-preview__list"></ul>
    178178            </div>
    179179            <label>
  • lipsum-dynamo/tags/3.2.0/includes/setting/setting.php

    r3117972 r3304136  
    1717    }
    1818   
    19     public function lipnamo_assets(){
    20         wp_enqueue_style('lipnamo-admin', LIPNAMO_ASSETS_URL . 'css/lipnamo-admin.css', false, DUMMIE_VERSION);
     19    public function lipnamo_assets($hook_suffix){
     20        if(!str_contains($hook_suffix, 'lipsum-dynamo')){
     21            return;
     22        }
     23       
     24        wp_enqueue_style('lipnamo-admin', LIPNAMO_ASSETS_URL . 'css/lipnamo-admin' . LIPNAMO_CSSJS_SUFFIX . '.css', false, LIPNAMO_VERSION);
    2125       
    2226        // Upload field
     
    2428       
    2529        // Plugin scripts
    26         wp_enqueue_script('lipnamo-admin', LIPNAMO_ASSETS_URL . 'js/lipnamo-admin.js', ['jquery'], DUMMIE_VERSION);
     30        wp_enqueue_script('lipnamo-admin', LIPNAMO_ASSETS_URL . 'js/lipnamo-admin' . LIPNAMO_CSSJS_SUFFIX . '.js', [
     31            'jquery',
     32            'media-upload',
     33            'media-views',
     34        ], LIPNAMO_VERSION);
    2735    }
    2836   
     
    8189       
    8290        $current_tab = lipnamo_array_key_exists('tab', $_GET) ? : 'general';
    83         if($current_tab == 'uninstall'){
     91        if($current_tab === 'uninstall'){
    8492            echo '<p class="description">' . __("When you uninstall this plugin, what do you want to do with your settings and the generated dummy items? Be careful to use this option. It can't be reverted.", "lipsum-dynamo") . '</p>';
    8593        }
     
    93101    }
    94102   
    95     public function lipnamo_setting_tabs(): array{
    96         $tabs = [
     103    public function lipnamo_setting_tabs(){
     104        return [
    97105            'general'   => 'General',
    98106            'cleanup'   => 'Cleanup',
    99107            'uninstall' => 'Uninstall',
    100108        ];
    101        
    102         return $tabs;
    103109    }
    104110   
     
    106112        $tabs = $this->lipnamo_setting_tabs();
    107113        foreach($tabs as $tab => $name){
    108             $class = ($tab == $current) ? ' nav-tab-active' : '';
     114            $class = ($tab === $current) ? ' nav-tab-active' : '';
    109115            echo "<a class='nav-tab$class' href='?page=lipsum-dynamo&tab=$tab' title='$name'>$name</a>";
    110116           
     
    130136        do_settings_sections('lipsum-dynamo-' . $current);
    131137       
    132         if($current == 'general' || $current == 'cleanup'){
    133             $btn = $current == 'general' ? 'generate' : $current;
     138        if($current === 'general' || $current === 'cleanup'){
     139            $button       = $current === 'general' ? 'generate' : $current;
     140            $button_title = ucfirst($button);
    134141            ?>
    135142            <input name="lipnamo-generate__step" type="hidden" value="1"/>
     
    143150                </div>
    144151            </div>
    145             <a href="#"
    146                class="lipnamo-<?php echo $btn; ?> button button-primary"><?php echo ucfirst($btn); ?></a>
     152            <a href="#" class="lipnamo-<?php echo $button; ?> button button-primary"
     153               title="<?php echo $button_title; ?>">
     154                <?php echo ucfirst($button_title); ?>
     155            </a>
    147156            <?php
    148157        }
    149158       
    150         if($current == 'cleanup'){
     159        if($current === 'cleanup'){
    151160            ?>
    152161            <input type="hidden" name="lipnamo_post_total" value=""/>
    153162            <?php
    154         }elseif($current == 'uninstall'){
     163        }elseif($current === 'uninstall'){
    155164            submit_button(null, 'primary', 'lipsum-dynamo-submit');
    156165        }
     
    159168    public function lipnamo_save_options(){
    160169        global $pagenow;
    161         if($pagenow == 'tools.php' && esc_attr(lipnamo_array_key_exists('page', $_GET)) == 'lipsum-dynamo'){
     170        if($pagenow === 'tools.php' && esc_attr(lipnamo_array_key_exists('page', $_GET)) === 'lipsum-dynamo'){
    162171            $option_key = 'lipsum-dynamo';
    163172            if(isset($_POST[$option_key])){
  • lipsum-dynamo/tags/3.2.0/lipsum-dynamo.php

    r3117972 r3304136  
    11<?php
    22/**
    3  * Plugin Name:       Dummie
     3 * Plugin Name:       Dummie (formerly Lipsum Dynamo)
    44 * Plugin URI:        https://wordpress.org/plugins/lipsum-dynamo/
    55 * Description:       🖨 Generate dummy content for demo purpose
    6  * Version:           3.1.0
     6 * Version:           3.2.0
    77 * Requires at least: 5.2
    8  * Requires PHP:      7.2
     8 * Requires PHP:      8.0
    99 * Author:            Dao
    1010 * Author URI:        https://daochau.com/
     
    2626 */
    2727
    28 const DUMMIE_VERSION = '3.1.0';
     28const LIPNAMO_VERSION      = '3.2.0';
     29const LIPNAMO_ENVIRONMENT  = 'production';
     30const LIPNAMO_CSSJS_SUFFIX = (LIPNAMO_ENVIRONMENT !== 'development') ? '.min' : '';
    2931define("LIPNAMO_DIR", plugin_dir_path(__FILE__));
    3032define("LIPNAMO_ASSETS_URL", plugin_dir_url(__FILE__) . 'assets/');
    3133
     34// libraries
     35require_once('vendor/LoremIpsum.php');
     36
    3237// helper functions
    33 include_once(LIPNAMO_DIR . 'includes/lorem-ipsum.php');
    34 include_once(LIPNAMO_DIR . 'includes/helper.php');
     38require_once(LIPNAMO_DIR . 'includes/helpers.php');
    3539
    3640/**
     
    3842 */
    3943
    40 add_action('init', 'lipnamo_init');
    41 function lipnamo_init(){
    42     // options pages
    43     include_once(LIPNAMO_DIR . 'includes/setting/setting.php');
    44     include_once(LIPNAMO_DIR . 'includes/setting/general.php');
    45     include_once(LIPNAMO_DIR . 'includes/setting/cleanup.php');
    46     include_once(LIPNAMO_DIR . 'includes/setting/data.php');
    47    
    48     // functions
    49     include_once(LIPNAMO_DIR . 'includes/generate-items.php');
    50     include_once(LIPNAMO_DIR . 'includes/cleanup.php');
    51 }
     44// options pages
     45require_once(LIPNAMO_DIR . 'includes/setting/setting.php');
     46require_once(LIPNAMO_DIR . 'includes/setting/general.php');
     47require_once(LIPNAMO_DIR . 'includes/setting/cleanup.php');
     48require_once(LIPNAMO_DIR . 'includes/setting/data.php');
     49
     50// functions
     51require_once(LIPNAMO_DIR . 'includes/generate-items.php');
     52require_once(LIPNAMO_DIR . 'includes/cleanup.php');
    5253
    5354/**
     
    7576        dbDelta($sql);
    7677       
    77         add_option('lipnamo_db_version', DUMMIE_VERSION);
     78        add_option('lipnamo_db_version', LIPNAMO_VERSION);
    7879    }
    7980}
     
    8182add_action('plugins_loaded', 'lipnamo_update_db_check');
    8283function lipnamo_update_db_check(){
    83     if(get_site_option('lipnamo_db_version') != DUMMIE_VERSION){
     84    if(get_site_option('lipnamo_db_version') !== LIPNAMO_VERSION){
    8485        lipnamo_install();
    8586    }
  • lipsum-dynamo/tags/3.2.0/readme.txt

    r3117973 r3304136  
    33Tags: lorem ipsum, dummy text generator, lorem ipsum generator
    44Requires at least: 4.7
    5 Tested up to: 6.5.5
     5Tested up to: 6.8.1
    66Requires PHP: 7.2
    7 Stable tag: 3.1.0
     7Stable tag: 3.2.0
    88License: GPLv2 or later
    99License URI: http://www.gnu.org/licenses/gpl-2.0.html
  • lipsum-dynamo/trunk/assets/css/lipnamo-admin.css

    r2621502 r3304136  
    1212
    1313.lipnamo-preview {
    14     max-width:500px; height:200px;
     14    height:300px; max-width:800px;
    1515    background-color:#fff;border:#ccd0d4 solid 1px;
    1616    margin-bottom:20px;overflow-x:auto;
    1717}
    1818.lipnamo-preview .lipnamo-input__img {margin-bottom:10px;}
    19 .lipnamo-preview .lipnamo-preview__list {display:flex; flex-wrap:wrap;}
    20 .lipnamo-preview .lipnamo-preview__list {padding:0 10px;}
    21 .lipnamo-preview .lipnamo-preview__list li {width:25%;}
    22 .lipnamo-preview .lipnamo-preview__list li span {
    23     display:block; padding:10px; margin:5px;
    24     background:#eee; border:#d5d9dd solid 1px;
     19
     20.lipnamo-preview .lipnamo-preview-item.attachment {width:16.66%;}
     21.lipnamo-preview .lipnamo-preview-item.attachment img {max-height:100%; max-width:100%;}
     22
     23/* Loading state for preview items */
     24.lipnamo-preview-item.lipnamo-loading .lipnamo-preview-wrapper {
     25    opacity:0.5;
     26    pointer-events:none;
    2527}
    26 .lipnamo-preview .lipnamo-preview__list li img {
    27     height:auto; max-height:100%;
    28     width:auto; max-width:100%;
     28
     29.lipnamo-preview-item.lipnamo-loading .lipnamo-preview-wrapper::after {
     30    content:"";
     31    position:absolute;
     32    top:50%;
     33    left:50%;
     34    width:20px;
     35    height:20px;
     36    margin:-10px 0 0 -10px;
     37    border:2px solid #ccc;
     38    border-top-color:#0073aa;
     39    border-radius:50%;
     40    animation:lipnamo-spin 1s linear infinite;
     41}
     42
     43@keyframes lipnamo-spin {
     44    to { transform:rotate(360deg); }
     45}
     46
     47/* Empty state */
     48.lipnamo-preview__list:empty::after {
     49    content:"No images selected. Click 'Upload Images' to add some.";
     50    display:block;
     51    padding:20px;
     52    text-align:center;
     53    color:#666;
     54    font-style:italic;
    2955}
    3056
     
    3359 */
    3460
    35 .lipnamo-length-control input {margin:0 0 1em;}
     61.lipnamo-length-control input {margin:0 0 16px;}
    3662.lipnamo-length-control label, .lipnamo-length-control select {
    37     display:inline-block;min-width:10em;vertical-align:middle;
    38     margin:.35em 0 .75em !important;
     63    display:inline-block;min-width:160px;vertical-align:middle;
     64    margin:6px 0 12px !important;
    3965}
    4066
     
    4369 */
    4470
    45 .lipnamo-progress-wrapper {max-width:1000px;margin-bottom:20px;background-color:#fff; padding:15px 10px;}
    46 .lipnamo-progress {margin-bottom:5px;color:#000;background-color:#cecece;}
     71.lipnamo-progress-wrapper {
     72    max-width:1000px;
     73    margin-bottom:20px;
     74    background-color:#fff;
     75    padding:15px 10px;
     76    border:1px solid #c3c4c7;
     77    border-radius:4px;
     78}
     79
     80.lipnamo-progress {
     81    margin-bottom:5px;
     82    color:#1d2327;
     83    background-color:#dcdcde;
     84    border-radius:3px;
     85    overflow:hidden;
     86    height:20px;
     87}
     88
    4789.lipnamo-progress-bar {
    48     height:20px;padding:0.01em 0;background-color:#0073aa;
     90    height:20px;
     91    padding:1px 0;
     92    background-color:#2271b1;
     93    border-radius:2px;
     94    transition:width 0.3s ease;
    4995}
  • lipsum-dynamo/trunk/assets/js/lipnamo-admin.js

    r2595116 r3304136  
    11jQuery(document).ready(function($){
     2    'use strict';
     3
     4    // Cache frequently used selectors
     5    const $thumbnailsField = $('#lipnamo-thumbnails');
     6
    27    /**
    3      * Upload field
     8     * Toggle preview visibility based on input value
    49     */
    5     // show hide preview
    610    $('.lipnamo-input__img input[type="text"]').on('change', function(){
    7         const preview = $(this).closest('fieldset').find('img');
    8         if(!$(this).val()){
    9             preview.hide();
    10         }else{
    11             preview.show();
    12         }
     11        const $preview = $(this).closest('fieldset').find('img');
     12        $preview.toggle(!!$(this).val());
    1313    });
    1414
    15     // preview
     15    /**
     16     * Media uploader functionality
     17     */
    1618    $('.lipnamo-upload').each(function(){
    17         const upload_element = $(this),
    18             preview = upload_element.closest('fieldset').find('.lipnamo-preview__list');
     19        const $uploadButton = $(this);
     20        const $preview = $uploadButton.closest('fieldset').find('.lipnamo-preview__list');
     21        let mediaUploader;
    1922
    20         let custom_uploader;
     23        $uploadButton.on('click', function(e){
     24            e.preventDefault();
    2125
    22         upload_element.click(function(e){
    23             e.preventDefault();
    24             //If the uploader object has already been created, reopen the dialog
    25             if(custom_uploader){
    26                 custom_uploader.open();
     26            // Reopen existing uploader
     27            if(mediaUploader){
     28                mediaUploader.open();
    2729                return;
    2830            }
    29             //Extend the wp.media object
    30             custom_uploader = wp.media.frames.file_frame = wp.media({
    31                 title: 'Choose Image',
    32                 button: {
    33                     text: 'Choose Image'
    34                 },
    35                 multiple: 'add'
    36             });
    37             //When a file is selected, grab the URL and set it as the text field's value
    38             custom_uploader.on('select', function(){
    39                 const attachment = custom_uploader.state().get('selection').toJSON(),
    40                     $thumbnails = $('#lipnamo-thumbnails');
    4131
    42                 let thumbnail_val = $thumbnails.val();
    43 
    44                 if(attachment){
    45                     for(let i = 0; i < attachment.length; i++){
    46                         thumbnail_val = $thumbnails.val();
    47                         if(thumbnail_val){
    48                             $thumbnails.val(thumbnail_val + ',' + attachment[i].id);
    49                             let thumbnail_array = thumbnail_val.split(",").map(Number);
    50                             if(!thumbnail_array.includes(attachment[i].id)){
    51                                 preview.append('<li><span><img src="' + attachment[i].url + '" /></span></li>');
    52                             }
    53                         }else{
    54                             $thumbnails.val(attachment[i].id);
    55                             preview.append('<li><span><img src="' + attachment[i].url + '" /></span></li>');
    56                         }
    57                     }
     32            // Create new media uploader
     33            mediaUploader = wp.media({
     34                title: 'Choose Images',
     35                button: {text: 'Choose Images'},
     36                multiple: 'add',
     37                library: {
     38                    type: 'image'
    5839                }
    5940            });
    60             //Show selected items when open media popup
    61             custom_uploader.on('open', function(){
    62                 const selection = custom_uploader.state().get('selection'),
    63                     ids_value = $('#lipnamo-thumbnails').val();
    6441
    65                 if(ids_value.length > 0){
    66                     var ids = ids_value.split(',');
     42            // Handle media selection
     43            mediaUploader.on('select', function(){
     44                const attachments = mediaUploader.state().get('selection').toJSON();
     45                lipnamoAddSelectedImages(attachments, $preview);
     46            });
    6747
    68                     ids.forEach(function(id){
    69                         let attachment = wp.media.attachment(id);
    70                         attachment.fetch();
    71                         selection.add(attachment ? [attachment] : []);
    72                     });
    73                 }
     48            // Pre-select existing images when opening
     49            mediaUploader.on('open', function(){
     50                lipnamoPreselectExistingImages(mediaUploader);
    7451            });
    75             //Open the uploader dialog
    76             custom_uploader.open();
     52
     53            mediaUploader.open();
    7754        });
    7855    });
     56
     57    /**
     58     * Remove thumbnail functionality
     59     */
     60    $(document).on('click', '.lipnamo-remove-thumbnail', function(e){
     61        e.preventDefault();
     62
     63        const imageId = parseInt($(this).data('lipnamo-id'));
     64        const $previewItem = $(this).closest('.lipnamo-preview-item');
     65
     66        lipnamoRemoveImageFromField(imageId);
     67        $previewItem.fadeOut(300, function(){
     68            $(this).remove();
     69        });
     70    });
     71
     72    /**
     73     * Add selected images to preview and update field
     74     */
     75    function lipnamoAddSelectedImages(attachments, $preview){
     76        if(!attachments?.length) return;
     77
     78        const currentIds = lipnamoGetCurrentImageIds();
     79        const newIds = [];
     80
     81        attachments.forEach((attachment, index) => {
     82            const imageId = parseInt(attachment.id);
     83
     84            // Skip if image already exists
     85            if(currentIds.includes(imageId)) return;
     86
     87            // Add to new IDs array
     88            newIds.push(imageId);
     89
     90            // Add to preview
     91            const altText = attachment.alt || `Image ${index + 1}`;
     92            $preview.append(lipnamoCreateThumbnailHTML(imageId, attachment.url, altText));
     93        });
     94
     95        // Update hidden field with combined IDs
     96        if(newIds.length){
     97            lipnamoUpdateThumbnailField([...currentIds, ...newIds]);
     98        }
     99    }
     100
     101    /**
     102     * Create thumbnail HTML
     103     */
     104    function lipnamoCreateThumbnailHTML(imageId, imageUrl, altText){
     105        return `
     106            <li class="lipnamo-preview-item attachment" data-lipnamo-id="${imageId}">
     107                <div class="attachment-preview">
     108                    <div class="thumbnail">
     109                        <div class="centered">
     110                            <img src="${imageUrl}" alt="${altText}" class="lipnamo-preview-image" />
     111                        </div>
     112                    </div>
     113                    <button type="button" class="lipnamo-remove-thumbnail button-link attachment-close media-modal-icon"
     114                            data-lipnamo-id="${imageId}" title="Remove image" aria-label="Remove image">
     115                        <span class="screen-reader-text">Remove</span>
     116                    </button>
     117                </div>
     118            </li>
     119        `;
     120    }
     121
     122    /**
     123     * Get current image IDs from hidden field
     124     */
     125    function lipnamoGetCurrentImageIds(){
     126        const value = $thumbnailsField.val().trim();
     127        return value ? value.split(',').map(id => parseInt(id.trim())).filter(id => !isNaN(id)) : [];
     128    }
     129
     130    /**
     131     * Update thumbnail field with new IDs
     132     */
     133    function lipnamoUpdateThumbnailField(imageIds){
     134        const uniqueIds = [...new Set(imageIds)].filter(id => !isNaN(id));
     135        $thumbnailsField.val(uniqueIds.length ? uniqueIds.join(',') : '');
     136    }
     137
     138    /**
     139     * Remove image ID from hidden field
     140     */
     141    function lipnamoRemoveImageFromField(imageId){
     142        const currentIds = lipnamoGetCurrentImageIds();
     143        const updatedIds = currentIds.filter(id => id !== imageId);
     144        lipnamoUpdateThumbnailField(updatedIds);
     145    }
     146
     147    /**
     148     * Pre-select existing images in media uploader
     149     */
     150    function lipnamoPreselectExistingImages(uploader){
     151        const imageIds = lipnamoGetCurrentImageIds();
     152        if(!imageIds.length) return;
     153
     154        const selection = uploader.state().get('selection');
     155
     156        imageIds.forEach(id => {
     157            const attachment = wp.media.attachment(id);
     158            attachment.fetch();
     159            selection.add(attachment);
     160        });
     161    }
    79162});
  • lipsum-dynamo/trunk/assets/js/lipnamo-cleanup-items.js

    r2621502 r3304136  
    1 jQuery(document).ready(function($){
    2     const $wpbody = $("#wpbody"), $cleanupButton = $('.lipnamo-cleanup.button');
    3 
    4     // Update post total
    5     $('select[name="lipnamo_post_type"]').on('change', function(){
    6         const post_type = $('select[name="lipnamo_post_type"]').val();
    7 
    8         $wpbody.addClass("lipnamo-loading");
    9         $cleanupButton.addClass('disabled');
    10 
    11         $.ajax({
    12             url: lipnamo_items.ajax_url,
    13             type: 'POST',
    14             data: {
    15                 action: 'lipnamo_total_items',
    16                 lipnamo_ajax_nonce: lipnamo_items.ajax_nonce,
    17                 post_type: post_type
    18             },
    19             success: function(response){
    20                 let result = JSON.parse(response),
    21                     post_total = parseInt(result.post_total);
    22 
    23                 $('input[name="lipnamo_post_total"]').val(post_total);
    24 
    25                 $wpbody.removeClass("lipnamo-loading");
    26                 $cleanupButton.removeClass('disabled');
    27             }
    28         });
    29     });
    30 
    31     // AJAX Cleanup
    32     let ajaxIndex = 1;
    33 
    34     $cleanupButton.click(function(e){
    35         e.preventDefault();
    36         lipnamoCleanupItems();
    37     });
    38 
    39     function lipnamoCleanupItems(){
    40         const post_total = parseInt($('input[name="lipnamo_post_total"]').val()),
    41             post_type = $('select[name="lipnamo_post_type"]').val(),
    42             $progressBar = $('.lipnamo-progress-bar');
    43 
    44         $wpbody.addClass("lipnamo-loading");
    45         $(".lipnamo-progress-wrapper").show();
    46         $(this).addClass('disabled');
    47 
    48         if(ajaxIndex > post_total){
     1class LipnamoCleanupManager{
     2    constructor(){
     3        this.currentStep = 1;
     4        this.isRunning = false;
     5        this.config = {};
     6        this.elements = {};
     7
     8        this.init();
     9    }
     10
     11    init(){
     12        this.cacheElements();
     13        this.bindEvents();
     14    }
     15
     16    cacheElements(){
     17        this.elements = {
     18            wpBody: document.getElementById('wpbody'),
     19            cleanupButton: document.querySelector('.lipnamo-cleanup.button'),
     20            progressBar: document.querySelector('.lipnamo-progress-bar'),
     21            progressWrapper: document.querySelector('.lipnamo-progress-wrapper'),
     22            progressStep: document.querySelector('.lipnamo-progress-step'),
     23            progressTotal: document.querySelector('.lipnamo-progress-total'),
     24            progressText: document.querySelector('.lipnamo-progress-text'),
     25            stepInput: document.querySelector('input[name="lipnamo-cleanup__step"]'),
     26            // Form inputs
     27            postTotalInput: document.querySelector('input[name="lipnamo_post_total"]'),
     28            postTypeSelect: document.querySelector('select[name="lipnamo_post_type"]')
     29        };
     30    }
     31
     32    bindEvents(){
     33        if(this.elements.postTypeSelect){
     34            this.elements.postTypeSelect.addEventListener('change', () => {
     35                this.updatePostTotal();
     36            });
     37        }
     38
     39        if(this.elements.cleanupButton){
     40            this.elements.cleanupButton.addEventListener('click', (e) => {
     41                e.preventDefault();
     42                this.startCleanup();
     43            });
     44        }
     45    }
     46
     47    async updatePostTotal(){
     48        const postType = this.elements.postTypeSelect?.value || '';
     49
     50        this.showLoading();
     51        this.disableCleanupButton();
     52
     53        try{
     54            const formData = new FormData();
     55            formData.append('action', 'lipnamo_total_items');
     56            formData.append('lipnamo_ajax_nonce', lipnamo_items.ajax_nonce);
     57            formData.append('post_type', postType);
     58
     59            const response = await fetch(lipnamo_items.ajax_url, {
     60                method: 'POST',
     61                body: formData,
     62                credentials: 'same-origin'
     63            });
     64
     65            if(!response.ok){
     66                throw new Error(`HTTP error! status: ${response.status}`);
     67            }
     68
     69            const responseText = await response.text();
     70            const result = JSON.parse(responseText);
     71            const postTotal = parseInt(result.post_total) || 0;
     72
     73            if(this.elements.postTotalInput){
     74                this.elements.postTotalInput.value = postTotal;
     75            }
     76
     77        }catch(error){
     78            console.error('LipnamoCleanupManager: Error updating post total', error);
     79        }finally{
     80            this.hideLoading();
     81            this.enableCleanupButton();
     82        }
     83    }
     84
     85    startCleanup(){
     86        if(this.isRunning) return;
     87
     88        this.config = this.getCleanupConfig();
     89        this.currentStep = 1;
     90        this.isRunning = true;
     91
     92        this.showProgress();
     93        if(this.elements.progressTotal){
     94            this.elements.progressTotal.textContent = this.config.postTotal;
     95        }
     96
     97        this.lipnamoCleanupItems();
     98    }
     99
     100    getCleanupConfig(){
     101        return {
     102            postTotal: parseInt(this.elements.postTotalInput?.value) || 0,
     103            postType: this.elements.postTypeSelect?.value || ''
     104        };
     105    }
     106
     107    showLoading(){
     108        if(this.elements.wpBody){
     109            this.elements.wpBody.classList.add('lipnamo-loading');
     110        }
     111    }
     112
     113    hideLoading(){
     114        if(this.elements.wpBody){
     115            this.elements.wpBody.classList.remove('lipnamo-loading');
     116        }
     117    }
     118
     119    showProgress(){
     120        this.showLoading();
     121        if(this.elements.progressWrapper){
     122            this.elements.progressWrapper.style.display = 'block';
     123        }
     124        this.disableCleanupButton();
     125    }
     126
     127    hideProgress(){
     128        this.hideLoading();
     129        this.enableCleanupButton();
     130        this.isRunning = false;
     131    }
     132
     133    disableCleanupButton(){
     134        if(this.elements.cleanupButton){
     135            this.elements.cleanupButton.classList.add('disabled');
     136        }
     137    }
     138
     139    enableCleanupButton(){
     140        if(this.elements.cleanupButton){
     141            this.elements.cleanupButton.classList.remove('disabled');
     142        }
     143    }
     144
     145    updateProgress(step, total){
     146        const percent = Math.min((step * 100) / total, 100);
     147
     148        if(this.elements.progressStep){
     149            this.elements.progressStep.textContent = step;
     150        }
     151        if(this.elements.stepInput){
     152            this.elements.stepInput.value = step;
     153        }
     154
     155        if(this.elements.progressBar){
     156            this.animateProgressBar(percent);
     157        }
     158    }
     159
     160    animateProgressBar(targetPercent){
     161        const progressBar = this.elements.progressBar;
     162        const currentWidth = parseFloat(progressBar.style.width) || 0;
     163        const targetWidth = targetPercent;
     164        const duration = 150;
     165        const startTime = performance.now();
     166
     167        const animate = (currentTime) => {
     168            const elapsed = currentTime - startTime;
     169            const progress = Math.min(elapsed / duration, 1);
     170
     171            // Easing function (ease-out)
     172            const easeOut = 1 - Math.pow(1 - progress, 3);
     173            const currentPercent = currentWidth + (targetWidth - currentWidth) * easeOut;
     174
     175            progressBar.style.width = `${currentPercent}%`;
     176
     177            if(progress < 1){
     178                requestAnimationFrame(animate);
     179            }
     180        };
     181
     182        requestAnimationFrame(animate);
     183    }
     184
     185    async lipnamoCleanupItems(){
     186        if(this.currentStep > this.config.postTotal){
     187            this.hideProgress();
    49188            return;
    50189        }
    51190
    52         // Update progress total
    53         $('.lipnamo-progress-total').text(post_total);
    54 
    55         // Deleting items
    56         $.ajax({
    57             url: lipnamo_items.ajax_url,
    58             type: 'POST',
    59             data: {
    60                 action: 'lipnamo_cleanup_items',
    61                 lipnamo_ajax_nonce: lipnamo_items.ajax_nonce,
    62                 post_total: post_total,
    63                 post_type: post_type,
    64                 post_step: ajaxIndex
    65             },
    66             success: function(response){
    67                 let result = JSON.parse(response),
    68                     step = parseInt(result.step),
    69                     percent = step * 100 / post_total;
    70 
    71                 $('input[name="lipnamo-cleanup__step"]').val(step);
    72 
    73                 if(step < post_total){
    74                     $('.lipnamo-progress-step').text(step);
    75                     $progressBar.animate({
    76                         width: percent + '%'
    77                     }, 150);
    78                 }else{
    79                     $progressBar.animate({
    80                         width: '100%'
    81                     }, 150);
    82                     $('.lipnamo-progress-text').text(result.message);
     191        try{
     192            const formData = new FormData();
     193            formData.append('action', 'lipnamo_cleanup_items');
     194            formData.append('lipnamo_ajax_nonce', lipnamo_items.ajax_nonce);
     195            formData.append('post_total', this.config.postTotal);
     196            formData.append('post_type', this.config.postType);
     197            formData.append('post_step', this.currentStep);
     198
     199            const response = await fetch(lipnamo_items.ajax_url, {
     200                method: 'POST',
     201                body: formData,
     202                credentials: 'same-origin'
     203            });
     204
     205            if(!response.ok){
     206                throw new Error(`HTTP error! status: ${response.status}`);
     207            }
     208
     209            const responseText = await response.text();
     210            await this.handleSuccess(responseText);
     211
     212        }catch(error){
     213            this.handleError(error);
     214        }
     215    }
     216
     217    async handleSuccess(responseText){
     218        try{
     219            const result = JSON.parse(responseText);
     220            const step = parseInt(result.step) || this.currentStep;
     221
     222            this.updateProgress(step, this.config.postTotal);
     223
     224            if(step >= this.config.postTotal){
     225                if(this.elements.progressText){
     226                    this.elements.progressText.textContent = result.message || 'Cleanup completed!';
    83227                }
    84 
    85                 //do your thing
    86                 ajaxIndex++;
    87                 //go to next iteration of the loop
    88                 lipnamoCleanupItems();
    89             }
    90         });
    91 
    92         $wpbody.removeClass("lipnamo-loading");
    93         $(this).removeClass('disabled');
    94     }
     228                this.hideProgress();
     229                return;
     230            }
     231
     232            this.currentStep = step + 1;
     233
     234            // Add small delay to prevent overwhelming the server
     235            setTimeout(() => {
     236                if(this.isRunning){
     237                    this.lipnamoCleanupItems();
     238                }
     239            }, 100);
     240
     241        }catch(error){
     242            console.error('LipnamoCleanupManager: Error parsing response', error);
     243            this.handleError(error);
     244        }
     245    }
     246
     247    handleError(error){
     248        console.error('LipnamoCleanupManager: Error', error);
     249        if(this.elements.progressText){
     250            this.elements.progressText.textContent = 'An error occurred during cleanup. Please try again.';
     251        }
     252        this.hideProgress();
     253    }
     254
     255    // Public methods for external access
     256    stop(){
     257        this.isRunning = false;
     258        this.hideProgress();
     259    }
     260
     261    reset(){
     262        this.stop();
     263        this.currentStep = 1;
     264        if(this.elements.progressBar){
     265            this.elements.progressBar.style.width = '0%';
     266        }
     267        if(this.elements.progressStep){
     268            this.elements.progressStep.textContent = '0';
     269        }
     270        if(this.elements.progressText){
     271            this.elements.progressText.textContent = '';
     272        }
     273        if(this.elements.stepInput){
     274            this.elements.stepInput.value = '';
     275        }
     276    }
     277
     278    getStatus(){
     279        return {
     280            isRunning: this.isRunning,
     281            currentStep: this.currentStep,
     282            totalSteps: this.config.postTotal,
     283            postType: this.config.postType
     284        };
     285    }
     286}
     287
     288document.addEventListener('DOMContentLoaded', function(){
     289    new LipnamoCleanupManager();
    95290});
  • lipsum-dynamo/trunk/assets/js/lipnamo-generate-items.js

    r2621502 r3304136  
    11jQuery(document).ready(function($){
    2     let i = 1;
     2    let lipnamoCurrentStep = 1;
    33
    44    $('.lipnamo-generate').click(function(e){
     
    2626        $(this).addClass('disabled');
    2727
    28         if(i > post_total){
     28        // stop when current step is greater than total posts
     29        if(lipnamoCurrentStep > post_total){
    2930            return;
    3031        }
     
    4849                post_excerpt_length: post_excerpt_min + ',' + post_excerpt_max,
    4950                post_body_length: post_body_min + ',' + post_body_max,
    50                 post_step: i
     51                post_step: lipnamoCurrentStep
    5152            },
    5253            success: function(response){
     
    6970                }
    7071
    71                 //do your thing
    72                 i++;
    73                 //go to next iteration of the loop
     72                // increase step
     73                lipnamoCurrentStep++;
     74
     75                //continue generating items
    7476                lipnamoGenerateItems();
    7577            }
  • lipsum-dynamo/trunk/changelog.txt

    r3117972 r3304136  
    11== Changelog ==
     2
     3= 3.2.0 =
     4*Release Date - 01 June 2025*
     5
     6* New: Add option to remove specific thumbnails.
     7* New: Add list format with a tag in post content.
     8* Changed: Inherit media style from WordPress core.
     9* Changed: Optimize code for better performance.
     10* Changed: Tested up to 6.8.1.
    211
    312= 3.1.0 =
  • lipsum-dynamo/trunk/includes/cleanup.php

    r3117972 r3304136  
    2020   
    2121    public function lipnamo_cleanup_scripts($hook_suffix){
    22         if(strpos($hook_suffix, 'lipsum-dynamo') !== false){
    23             wp_enqueue_script('lipnamo-cleanup-items', LIPNAMO_ASSETS_URL . 'js/lipnamo-cleanup-items.js', ['jquery'], DUMMIE_VERSION, true);
     22        if(str_contains($hook_suffix, 'lipsum-dynamo')){
     23            wp_enqueue_script('lipnamo-cleanup-items', LIPNAMO_ASSETS_URL . 'js/lipnamo-cleanup-items' . LIPNAMO_CSSJS_SUFFIX . '.js', false, LIPNAMO_VERSION, true);
    2424            wp_localize_script('lipnamo-cleanup-items', 'lipnamo_items',
    2525                [
     
    4343       
    4444        // Get AJAX data
    45         $post_total = intval(lipnamo_array_key_exists('post_total', $_POST, 10));
     45        $post_total = (int) lipnamo_array_key_exists('post_total', $_POST, 10);
    4646        $post_type  = sanitize_text_field(lipnamo_array_key_exists('post_type', $_POST, 'any'));
    47         $post_step  = intval(lipnamo_array_key_exists('post_step', $_POST));
     47        $post_step  = (int) lipnamo_array_key_exists('post_step', $_POST);
    4848       
    4949        // Exit if invalid post type
     
    6969            if($posts){
    7070                foreach($posts as $post){
    71                     $post_id = intval($post->post_id);
     71                    $post_id = (int) $post->post_id;
    7272                    if(get_post_status($post_id)){
    7373                        wp_delete_post($post_id, true);
     
    9494       
    9595        // Send output as JSON for processing via AJAX.
    96         echo json_encode($result);
     96        echo json_encode($result, JSON_THROW_ON_ERROR);
    9797        exit;
    9898    }
     
    124124       
    125125        $table_name = $wpdb->prefix . 'lipnamo';
    126         if($post_type == "any"){
     126        if($post_type === "any"){
    127127            $mysql_query = "SELECT * FROM $table_name";
    128128        }else{
     
    137137       
    138138        // Send output as JSON for processing via AJAX.
    139         echo json_encode($result);
     139        echo json_encode($result, JSON_THROW_ON_ERROR);
    140140        exit;
    141141    }
  • lipsum-dynamo/trunk/includes/generate-items.php

    r3117972 r3304136  
    1919   
    2020    public function lipnamo_generate_scripts($hook_suffix){
    21         if(strpos($hook_suffix, 'lipsum-dynamo') !== false){
    22             wp_enqueue_script('lipnamo-generate-items', LIPNAMO_ASSETS_URL . 'js/lipnamo-generate-items.js', ['jquery'], DUMMIE_VERSION, true);
     21        if(str_contains($hook_suffix, 'lipsum-dynamo')){
     22            wp_enqueue_script('lipnamo-generate-items', LIPNAMO_ASSETS_URL . 'js/lipnamo-generate-items.js', false, LIPNAMO_VERSION, true);
    2323            wp_localize_script('lipnamo-generate-items', 'lipnamo_items',
    2424                [
     
    4242       
    4343        // Get AJAX data
    44         $post_total          = intval(lipnamo_array_key_exists('post_total', $_POST, 10));
     44        $post_total          = (int) lipnamo_array_key_exists('post_total', $_POST, 10);
    4545        $post_type           = sanitize_text_field(lipnamo_array_key_exists('post_type', $_POST, 'post'));
    46         $post_author         = intval(lipnamo_array_key_exists('post_author', $_POST));
     46        $post_author         = (int) lipnamo_array_key_exists('post_author', $_POST);
    4747        $post_status         = sanitize_text_field(lipnamo_array_key_exists('post_status', $_POST, 'publish'));
    4848        $post_thumbnails     = sanitize_text_field(lipnamo_array_key_exists('post_thumbnails', $_POST));
     
    5050        $post_excerpt_length = sanitize_text_field(lipnamo_array_key_exists('post_excerpt_length', $_POST));
    5151        $post_body_length    = sanitize_text_field(lipnamo_array_key_exists('post_body_length', $_POST));
    52         $post_step           = intval(lipnamo_array_key_exists('post_step', $_POST));
     52        $post_step           = (int) lipnamo_array_key_exists('post_step', $_POST);
    5353       
    5454        // Exit if invalid post type
     
    6262        if($post_title_length){
    6363            $post_title_array = explode(',', $post_title_length);
    64             $post_title_min   = intval($post_title_array[0]);
    65             $post_title_max   = intval($post_title_array[1]);
     64            $post_title_min   = (int) $post_title_array[0];
     65            $post_title_max   = (int) $post_title_array[1];
    6666        }
    6767        $post_excerpt_min = $post_excerpt_max = 1;
    6868        if($post_excerpt_length){
    6969            $post_excerpt_array = explode(',', $post_excerpt_length);
    70             $post_excerpt_min   = intval($post_excerpt_array[0]);
    71             $post_excerpt_max   = intval($post_excerpt_array[1]);
     70            $post_excerpt_min   = (int) $post_excerpt_array[0];
     71            $post_excerpt_max   = (int) $post_excerpt_array[1];
    7272        }
    7373        $post_body_min = $post_body_max = 1;
    7474        if($post_body_length){
    7575            $post_body_array = explode(',', $post_body_length);
    76             $post_body_min   = intval($post_body_array[0]);
    77             $post_body_max   = intval($post_body_array[1]);
     76            $post_body_min   = (int) $post_body_array[0];
     77            $post_body_max   = (int) $post_body_array[1];
    7878        }
    7979       
     
    9292            }
    9393           
     94            // prevent lorem ipsum from generating the same word twice in a row
    9495            if($post_step > 1){
    9596                $generator->word();
    9697            }
     98           
     99            // variables
    97100            $post_title   = ucfirst($generator->words($title_words));
    98101            $post_excerpt = $generator->sentences($excerpt_sentences);
    99             $post_content = $generator->paragraphs($content_paragraphs);
     102            $post_content = '<ul>';
     103            for($list_index = 0;$list_index < 3;$list_index ++){
     104                $list_title   = $generator->words(5);
     105                $post_content .= '<li><a href="#" title="' . $list_title . '">' . $list_title . '</a></li>';
     106               
     107            }
     108            $post_content .= '</ul>';
     109            $post_content .= $generator->paragraphs($content_paragraphs - 1);
    100110           
    101111            // Create post
  • lipsum-dynamo/trunk/includes/setting/general.php

    r3117972 r3304136  
    174174        ?>
    175175        <fieldset class="lipnamo-input__img">
    176             <div class="lipnamo-preview">
    177                 <ul class="lipnamo-preview__list"></ul>
     176            <div class="lipnamo-preview attachments-wrapper">
     177                <ul class="attachments lipnamo-preview__list"></ul>
    178178            </div>
    179179            <label>
  • lipsum-dynamo/trunk/includes/setting/setting.php

    r3117972 r3304136  
    1717    }
    1818   
    19     public function lipnamo_assets(){
    20         wp_enqueue_style('lipnamo-admin', LIPNAMO_ASSETS_URL . 'css/lipnamo-admin.css', false, DUMMIE_VERSION);
     19    public function lipnamo_assets($hook_suffix){
     20        if(!str_contains($hook_suffix, 'lipsum-dynamo')){
     21            return;
     22        }
     23       
     24        wp_enqueue_style('lipnamo-admin', LIPNAMO_ASSETS_URL . 'css/lipnamo-admin' . LIPNAMO_CSSJS_SUFFIX . '.css', false, LIPNAMO_VERSION);
    2125       
    2226        // Upload field
     
    2428       
    2529        // Plugin scripts
    26         wp_enqueue_script('lipnamo-admin', LIPNAMO_ASSETS_URL . 'js/lipnamo-admin.js', ['jquery'], DUMMIE_VERSION);
     30        wp_enqueue_script('lipnamo-admin', LIPNAMO_ASSETS_URL . 'js/lipnamo-admin' . LIPNAMO_CSSJS_SUFFIX . '.js', [
     31            'jquery',
     32            'media-upload',
     33            'media-views',
     34        ], LIPNAMO_VERSION);
    2735    }
    2836   
     
    8189       
    8290        $current_tab = lipnamo_array_key_exists('tab', $_GET) ? : 'general';
    83         if($current_tab == 'uninstall'){
     91        if($current_tab === 'uninstall'){
    8492            echo '<p class="description">' . __("When you uninstall this plugin, what do you want to do with your settings and the generated dummy items? Be careful to use this option. It can't be reverted.", "lipsum-dynamo") . '</p>';
    8593        }
     
    93101    }
    94102   
    95     public function lipnamo_setting_tabs(): array{
    96         $tabs = [
     103    public function lipnamo_setting_tabs(){
     104        return [
    97105            'general'   => 'General',
    98106            'cleanup'   => 'Cleanup',
    99107            'uninstall' => 'Uninstall',
    100108        ];
    101        
    102         return $tabs;
    103109    }
    104110   
     
    106112        $tabs = $this->lipnamo_setting_tabs();
    107113        foreach($tabs as $tab => $name){
    108             $class = ($tab == $current) ? ' nav-tab-active' : '';
     114            $class = ($tab === $current) ? ' nav-tab-active' : '';
    109115            echo "<a class='nav-tab$class' href='?page=lipsum-dynamo&tab=$tab' title='$name'>$name</a>";
    110116           
     
    130136        do_settings_sections('lipsum-dynamo-' . $current);
    131137       
    132         if($current == 'general' || $current == 'cleanup'){
    133             $btn = $current == 'general' ? 'generate' : $current;
     138        if($current === 'general' || $current === 'cleanup'){
     139            $button       = $current === 'general' ? 'generate' : $current;
     140            $button_title = ucfirst($button);
    134141            ?>
    135142            <input name="lipnamo-generate__step" type="hidden" value="1"/>
     
    143150                </div>
    144151            </div>
    145             <a href="#"
    146                class="lipnamo-<?php echo $btn; ?> button button-primary"><?php echo ucfirst($btn); ?></a>
     152            <a href="#" class="lipnamo-<?php echo $button; ?> button button-primary"
     153               title="<?php echo $button_title; ?>">
     154                <?php echo ucfirst($button_title); ?>
     155            </a>
    147156            <?php
    148157        }
    149158       
    150         if($current == 'cleanup'){
     159        if($current === 'cleanup'){
    151160            ?>
    152161            <input type="hidden" name="lipnamo_post_total" value=""/>
    153162            <?php
    154         }elseif($current == 'uninstall'){
     163        }elseif($current === 'uninstall'){
    155164            submit_button(null, 'primary', 'lipsum-dynamo-submit');
    156165        }
     
    159168    public function lipnamo_save_options(){
    160169        global $pagenow;
    161         if($pagenow == 'tools.php' && esc_attr(lipnamo_array_key_exists('page', $_GET)) == 'lipsum-dynamo'){
     170        if($pagenow === 'tools.php' && esc_attr(lipnamo_array_key_exists('page', $_GET)) === 'lipsum-dynamo'){
    162171            $option_key = 'lipsum-dynamo';
    163172            if(isset($_POST[$option_key])){
  • lipsum-dynamo/trunk/lipsum-dynamo.php

    r3117972 r3304136  
    11<?php
    22/**
    3  * Plugin Name:       Dummie
     3 * Plugin Name:       Dummie (formerly Lipsum Dynamo)
    44 * Plugin URI:        https://wordpress.org/plugins/lipsum-dynamo/
    55 * Description:       🖨 Generate dummy content for demo purpose
    6  * Version:           3.1.0
     6 * Version:           3.2.0
    77 * Requires at least: 5.2
    8  * Requires PHP:      7.2
     8 * Requires PHP:      8.0
    99 * Author:            Dao
    1010 * Author URI:        https://daochau.com/
     
    2626 */
    2727
    28 const DUMMIE_VERSION = '3.1.0';
     28const LIPNAMO_VERSION      = '3.2.0';
     29const LIPNAMO_ENVIRONMENT  = 'production';
     30const LIPNAMO_CSSJS_SUFFIX = (LIPNAMO_ENVIRONMENT !== 'development') ? '.min' : '';
    2931define("LIPNAMO_DIR", plugin_dir_path(__FILE__));
    3032define("LIPNAMO_ASSETS_URL", plugin_dir_url(__FILE__) . 'assets/');
    3133
     34// libraries
     35require_once('vendor/LoremIpsum.php');
     36
    3237// helper functions
    33 include_once(LIPNAMO_DIR . 'includes/lorem-ipsum.php');
    34 include_once(LIPNAMO_DIR . 'includes/helper.php');
     38require_once(LIPNAMO_DIR . 'includes/helpers.php');
    3539
    3640/**
     
    3842 */
    3943
    40 add_action('init', 'lipnamo_init');
    41 function lipnamo_init(){
    42     // options pages
    43     include_once(LIPNAMO_DIR . 'includes/setting/setting.php');
    44     include_once(LIPNAMO_DIR . 'includes/setting/general.php');
    45     include_once(LIPNAMO_DIR . 'includes/setting/cleanup.php');
    46     include_once(LIPNAMO_DIR . 'includes/setting/data.php');
    47    
    48     // functions
    49     include_once(LIPNAMO_DIR . 'includes/generate-items.php');
    50     include_once(LIPNAMO_DIR . 'includes/cleanup.php');
    51 }
     44// options pages
     45require_once(LIPNAMO_DIR . 'includes/setting/setting.php');
     46require_once(LIPNAMO_DIR . 'includes/setting/general.php');
     47require_once(LIPNAMO_DIR . 'includes/setting/cleanup.php');
     48require_once(LIPNAMO_DIR . 'includes/setting/data.php');
     49
     50// functions
     51require_once(LIPNAMO_DIR . 'includes/generate-items.php');
     52require_once(LIPNAMO_DIR . 'includes/cleanup.php');
    5253
    5354/**
     
    7576        dbDelta($sql);
    7677       
    77         add_option('lipnamo_db_version', DUMMIE_VERSION);
     78        add_option('lipnamo_db_version', LIPNAMO_VERSION);
    7879    }
    7980}
     
    8182add_action('plugins_loaded', 'lipnamo_update_db_check');
    8283function lipnamo_update_db_check(){
    83     if(get_site_option('lipnamo_db_version') != DUMMIE_VERSION){
     84    if(get_site_option('lipnamo_db_version') !== LIPNAMO_VERSION){
    8485        lipnamo_install();
    8586    }
  • lipsum-dynamo/trunk/readme.txt

    r3117973 r3304136  
    33Tags: lorem ipsum, dummy text generator, lorem ipsum generator
    44Requires at least: 4.7
    5 Tested up to: 6.5.5
     5Tested up to: 6.8.1
    66Requires PHP: 7.2
    7 Stable tag: 3.1.0
     7Stable tag: 3.2.0
    88License: GPLv2 or later
    99License URI: http://www.gnu.org/licenses/gpl-2.0.html
Note: See TracChangeset for help on using the changeset viewer.