Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Exclude repo file when updating my plugin #550

Open
nebestudio opened this issue Dec 13, 2023 · 2 comments
Open

Exclude repo file when updating my plugin #550

nebestudio opened this issue Dec 13, 2023 · 2 comments

Comments

@nebestudio
Copy link

Hello,

is there a way when updating a plugin with the repo content on github to exclude one settings file? It should be not synchronised, neither deleted.

When having this settings file (settings.php) in my plugin and update the plugin, it gets deleted every time, although I have .gitattributes file in my github repo with this content "settings.php export-ignore".

Thanks in advance!

@nebestudio nebestudio changed the title <?php define('REPO_URL', 'https://github.com/nebestudio/model-comparator-ro-dev'); define('REPO_NAME', 'model-comparator-ro-dev'); define('REPO_BRANCH', 'main'); define('REPO_TOKEN', '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'); Exclude repo file when updating my plugin Dec 13, 2023
@YahnisElsts
Copy link
Owner

It's been a while since I've looked at the relevant part of WordPress core, but I think that the WP plugin updater deletes the entire directory of the old version before installing a new version. So you can't preserve a file in the plugin directory even if the update doesn't include a new version of that file. It will get deleted anyway.

If you really have to keep a specific file unchanged, you might have to write a custom plugin update installer. PUC doesn't handle that part, it just hands the update to WordPress core.

@MarJC5
Copy link

MarJC5 commented Dec 24, 2024

Hi @nebestudio & @YahnisElsts,

I have a custom theme with a folder that I wanted to keep even after updates. To achieve this, I used the WordPress update hooks to preserve the folder. Here’s the code in case you need to do the same.

For scenarios where you need to preserve a specific folder (or file) during theme updates, you can use the following approach. It leverages the WordPress hooks upgrader_pre_install and upgrader_post_install to temporarily move the folder out of the theme directory before the update and restore it afterward.

Here’s a small class, PUCUpdateKeeper, that demonstrates how to achieve this:

<?php

class PUCUpdateKeeper {
    private $theme_slug;
    private $folder_to_preserve;
    private $temp_location;

    public function __construct($theme_slug, $folder_to_preserve) {
        $this->theme_slug = $theme_slug;
        $this->folder_to_preserve = get_theme_root() . '/' . $theme_slug . '/' . $folder_to_preserve;
        $this->temp_location = WP_CONTENT_DIR . '/temp-folder-to-preserve';

        add_filter('upgrader_pre_install', [$this, 'preserveFolderBeforeUpdate'], 10, 2);
        add_filter('upgrader_post_install', [$this, 'restoreFolderAfterUpdate'], 10, 3);
    }

    public function preserveFolderBeforeUpdate($response, $hook_extra) {
        if (isset($hook_extra['theme']) && $hook_extra['theme'] === $this->theme_slug) {
            if (file_exists($this->folder_to_preserve)) {
                if (!file_exists($this->temp_location)) {
                    mkdir($this->temp_location, 0755, true);
                }
                $this->recurseCopy($this->folder_to_preserve, $this->temp_location);
            }
        }
        return $response;
    }

    public function restoreFolderAfterUpdate($response, $hook_extra, $result) {
        if (isset($hook_extra['theme']) && $hook_extra['theme'] === $this->theme_slug) {
            if (file_exists($this->temp_location)) {
                $this->recurseCopy($this->temp_location, $this->folder_to_preserve);
                $this->deleteFolder($this->temp_location);
            }
        }
        return $response;
    }

    private function recurseCopy($src, $dst) {
        $dir = opendir($src);
        @mkdir($dst);
        while (($file = readdir($dir)) !== false) {
            if ($file !== '.' && $file !== '..') {
                if (is_dir($src . '/' . $file)) {
                    $this->recurseCopy($src . '/' . $file, $dst . '/' . $file);
                } else {
                    copy($src . '/' . $file, $dst . '/' . $file);
                }
            }
        }
        closedir($dir);
    }

    private function deleteFolder($folder) {
        if (!is_dir($folder)) {
            return;
        }
        $files = array_diff(scandir($folder), ['.', '..']);
        foreach ($files as $file) {
            $path = $folder . '/' . $file;
            if (is_dir($path)) {
                $this->deleteFolder($path);
            } else {
                unlink($path);
            }
        }
        rmdir($folder);
    }
}

// Initialize PUCUpdateKeeper for preserving the /<dir> folder.
add_action('after_setup_theme', function () {
    new PUCUpdateKeeper('your-theme-slug', 'folder-to-preserve');
});

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

3 participants