mirror of
https://github.com/soulsites/wp-git-installer.git
synced 2025-11-19 16:15:48 +08:00
Compare commits
8 commits
49d3ff746d
...
198324cf01
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
198324cf01 | ||
|
|
24943e6d9a | ||
|
|
49a11bad1b | ||
|
|
fec905eb50 | ||
|
|
3c50ea7fc4 | ||
|
|
440a124833 | ||
|
|
57acf60bfa | ||
|
|
fd8f65bd43 |
3 changed files with 550 additions and 47 deletions
39
README.md
39
README.md
|
|
@ -14,12 +14,16 @@ This plugin is designed for:
|
|||
|
||||
## Features
|
||||
|
||||
- **Multi-Project Support**: Save and manage multiple GitHub projects in one place
|
||||
- **Project Cards**: Visual card-based interface showing all your saved projects
|
||||
- **One-Click Sync**: Synchronize any saved project to pull the latest version from Git
|
||||
- Install plugins directly from public or private GitHub repositories
|
||||
- Update existing plugins installed from GitHub
|
||||
- Preview repository contents before installation
|
||||
- Select specific versions (tags) of a plugin to install
|
||||
- Support for private repositories using GitHub Personal Access Tokens
|
||||
- Automatic plugin folder naming based on the repository name
|
||||
- Track last synchronization time for each project
|
||||
|
||||
## Installation
|
||||
|
||||
|
|
@ -29,12 +33,33 @@ This plugin is designed for:
|
|||
|
||||
## Usage
|
||||
|
||||
### Installing a New Plugin
|
||||
|
||||
1. In the WordPress admin panel, go to Plugins > GitHub Installer.
|
||||
2. Enter the GitHub repository URL of the plugin you want to install.
|
||||
3. If it's a private repository, check the "Private Repository?" box and enter your GitHub Personal Access Token.
|
||||
4. The plugin will fetch available versions and provide a preview of the repository contents.
|
||||
5. Select the version you want to install from the dropdown menu.
|
||||
6. Click "Install/Update Plugin" to proceed with the installation or update.
|
||||
2. Enter a project name (optional) to save the project for later use.
|
||||
3. Enter the GitHub repository URL of the plugin you want to install.
|
||||
4. If it's a private repository, check the "Private Repository?" box and enter your GitHub Personal Access Token.
|
||||
5. The plugin will fetch available versions and provide a preview of the repository contents.
|
||||
6. Select the version you want to install from the dropdown menu.
|
||||
7. Click "Install/Update Plugin" to proceed with the installation or update.
|
||||
8. Optionally, click "Als Projekt speichern" (Save as Project) to save this configuration for future use.
|
||||
|
||||
### Managing Saved Projects
|
||||
|
||||
Once you've saved projects, they will appear as cards below the installation form:
|
||||
|
||||
- **View Project Details**: Each card shows the project name, repository URL, version, privacy status, and last sync time.
|
||||
- **Synchronize**: Click the "Synchronisieren" button to pull the latest version from Git for that specific project.
|
||||
- **Delete**: Click the "Löschen" button to remove a saved project from your list (this won't uninstall the plugin, just removes it from the saved projects).
|
||||
|
||||
### Synchronizing Projects
|
||||
|
||||
The synchronization feature allows you to quickly update any saved project:
|
||||
|
||||
1. Find the project card you want to sync.
|
||||
2. Click the "Synchronisieren" (Synchronize) button.
|
||||
3. The plugin will automatically fetch the latest version from Git and update the plugin.
|
||||
4. You'll see a status message indicating success or failure.
|
||||
|
||||
## Requirements
|
||||
|
||||
|
|
@ -57,8 +82,10 @@ No additional configuration is required after installation. However, for private
|
|||
## Security Considerations
|
||||
|
||||
- The plugin uses nonces and capability checks to ensure only authorized users can install plugins.
|
||||
- Personal Access Tokens are not stored by the plugin and must be entered each time for private repositories.
|
||||
- **Personal Access Tokens are stored in the WordPress database** when you save a project. Ensure your WordPress installation is secure.
|
||||
- Only users with the `manage_options` capability (typically administrators) can access the plugin.
|
||||
- Always review the contents of a repository before installing to ensure it's from a trusted source.
|
||||
- Saved projects and their tokens are stored using WordPress options API with proper sanitization.
|
||||
|
||||
## Limitations
|
||||
|
||||
|
|
|
|||
|
|
@ -1,8 +1,8 @@
|
|||
<?php
|
||||
/**
|
||||
* Plugin Name: GitHub Plugin Installer
|
||||
* Description: Install or update WordPress plugins directly from GitHub repositories
|
||||
* Version: 1.4
|
||||
* Description: Install or update WordPress plugins directly from GitHub repositories with multi-project support
|
||||
* Version: 2.0
|
||||
* Author: Christian Wedel
|
||||
*/
|
||||
|
||||
|
|
@ -12,6 +12,9 @@ add_action('admin_enqueue_scripts', 'github_plugin_installer_scripts');
|
|||
add_action('wp_ajax_preview_github_repo', 'preview_github_repo');
|
||||
add_action('wp_ajax_get_github_versions', 'get_github_versions');
|
||||
add_action('wp_ajax_check_plugin_status', 'check_plugin_status');
|
||||
add_action('wp_ajax_save_github_project', 'save_github_project');
|
||||
add_action('wp_ajax_delete_github_project', 'delete_github_project');
|
||||
add_action('wp_ajax_sync_github_project', 'sync_github_project');
|
||||
|
||||
function github_plugin_installer_menu() {
|
||||
add_plugins_page('GitHub Plugin Installer', 'GitHub Installer', 'manage_options', 'github-plugin-installer', 'github_plugin_installer_page');
|
||||
|
|
@ -28,6 +31,38 @@ function github_plugin_installer_scripts($hook) {
|
|||
));
|
||||
}
|
||||
|
||||
// Helper functions for project management
|
||||
function get_saved_projects() {
|
||||
$projects = get_option('github_installer_projects', array());
|
||||
return is_array($projects) ? $projects : array();
|
||||
}
|
||||
|
||||
function save_project($project_data) {
|
||||
$projects = get_saved_projects();
|
||||
$project_id = sanitize_title($project_data['name']);
|
||||
$projects[$project_id] = array(
|
||||
'id' => $project_id,
|
||||
'name' => sanitize_text_field($project_data['name']),
|
||||
'repo_url' => esc_url_raw($project_data['repo_url']),
|
||||
'is_private' => (bool) $project_data['is_private'],
|
||||
'access_token' => !empty($project_data['access_token']) ? sanitize_text_field($project_data['access_token']) : '',
|
||||
'version' => sanitize_text_field($project_data['version']),
|
||||
'last_synced' => current_time('mysql')
|
||||
);
|
||||
update_option('github_installer_projects', $projects);
|
||||
return $project_id;
|
||||
}
|
||||
|
||||
function delete_project($project_id) {
|
||||
$projects = get_saved_projects();
|
||||
if (isset($projects[$project_id])) {
|
||||
unset($projects[$project_id]);
|
||||
update_option('github_installer_projects', $projects);
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
function github_plugin_installer_page() {
|
||||
if (!current_user_can('manage_options')) {
|
||||
return;
|
||||
|
|
@ -38,46 +73,201 @@ function github_plugin_installer_page() {
|
|||
$is_private = isset($_POST['is_private']) ? true : false;
|
||||
$access_token = $is_private ? sanitize_text_field($_POST['access_token']) : '';
|
||||
$selected_version = sanitize_text_field($_POST['version']);
|
||||
|
||||
|
||||
install_update_github_plugin($repo_url, $access_token, $selected_version);
|
||||
}
|
||||
|
||||
$saved_projects = get_saved_projects();
|
||||
|
||||
?>
|
||||
<style>
|
||||
.github-projects-grid {
|
||||
display: grid;
|
||||
grid-template-columns: repeat(auto-fill, minmax(300px, 1fr));
|
||||
gap: 20px;
|
||||
margin: 20px 0;
|
||||
}
|
||||
.github-project-card {
|
||||
background: #fff;
|
||||
border: 1px solid #c3c4c7;
|
||||
border-radius: 4px;
|
||||
padding: 20px;
|
||||
box-shadow: 0 1px 1px rgba(0,0,0,.04);
|
||||
transition: box-shadow 0.2s ease;
|
||||
}
|
||||
.github-project-card:hover {
|
||||
box-shadow: 0 2px 6px rgba(0,0,0,.1);
|
||||
}
|
||||
.github-project-card h3 {
|
||||
margin-top: 0;
|
||||
margin-bottom: 10px;
|
||||
font-size: 16px;
|
||||
color: #1d2327;
|
||||
}
|
||||
.github-project-info {
|
||||
font-size: 13px;
|
||||
color: #50575e;
|
||||
margin-bottom: 15px;
|
||||
}
|
||||
.github-project-info p {
|
||||
margin: 5px 0;
|
||||
word-break: break-all;
|
||||
}
|
||||
.github-project-actions {
|
||||
display: flex;
|
||||
gap: 10px;
|
||||
flex-wrap: wrap;
|
||||
}
|
||||
.github-sync-btn {
|
||||
background: #2271b1;
|
||||
border-color: #2271b1;
|
||||
color: #fff;
|
||||
padding: 6px 12px;
|
||||
border-radius: 3px;
|
||||
cursor: pointer;
|
||||
border: 1px solid;
|
||||
font-size: 13px;
|
||||
transition: background 0.2s ease;
|
||||
}
|
||||
.github-sync-btn:hover {
|
||||
background: #135e96;
|
||||
border-color: #135e96;
|
||||
}
|
||||
.github-sync-btn:disabled {
|
||||
background: #c3c4c7;
|
||||
border-color: #c3c4c7;
|
||||
cursor: not-allowed;
|
||||
}
|
||||
.github-delete-btn {
|
||||
background: #fff;
|
||||
border-color: #c3c4c7;
|
||||
color: #b32d2e;
|
||||
padding: 6px 12px;
|
||||
border-radius: 3px;
|
||||
cursor: pointer;
|
||||
border: 1px solid;
|
||||
font-size: 13px;
|
||||
transition: all 0.2s ease;
|
||||
}
|
||||
.github-delete-btn:hover {
|
||||
background: #b32d2e;
|
||||
border-color: #b32d2e;
|
||||
color: #fff;
|
||||
}
|
||||
.github-sync-status {
|
||||
font-size: 12px;
|
||||
margin-top: 10px;
|
||||
padding: 8px;
|
||||
border-radius: 3px;
|
||||
display: none;
|
||||
}
|
||||
.github-sync-status.success {
|
||||
background: #d7f0db;
|
||||
color: #00631e;
|
||||
border: 1px solid #00631e;
|
||||
}
|
||||
.github-sync-status.error {
|
||||
background: #fcf0f1;
|
||||
color: #b32d2e;
|
||||
border: 1px solid #b32d2e;
|
||||
}
|
||||
.github-sync-status.loading {
|
||||
background: #f0f6fc;
|
||||
color: #1d2327;
|
||||
border: 1px solid #2271b1;
|
||||
}
|
||||
.github-add-project-section {
|
||||
background: #fff;
|
||||
border: 1px solid #c3c4c7;
|
||||
border-radius: 4px;
|
||||
padding: 20px;
|
||||
margin-bottom: 30px;
|
||||
}
|
||||
.github-save-project-btn {
|
||||
background: #00a32a;
|
||||
border-color: #00a32a;
|
||||
color: #fff;
|
||||
margin-left: 10px;
|
||||
}
|
||||
.github-save-project-btn:hover {
|
||||
background: #008a20;
|
||||
border-color: #008a20;
|
||||
}
|
||||
</style>
|
||||
<div class="wrap">
|
||||
<h1><?php echo esc_html(get_admin_page_title()); ?></h1>
|
||||
<form method="post" action="">
|
||||
<table class="form-table">
|
||||
<tr>
|
||||
<th scope="row"><label for="repo_url">GitHub Repository URL</label></th>
|
||||
<td><input type="text" id="repo_url" name="repo_url" class="regular-text" required placeholder="https://github.com/username/repo.git"></td>
|
||||
</tr>
|
||||
<tr>
|
||||
<th scope="row"><label for="is_private">Private Repository?</label></th>
|
||||
<td><input type="checkbox" id="is_private" name="is_private"></td>
|
||||
</tr>
|
||||
<tr id="access_token_row" style="display: none;">
|
||||
<th scope="row"><label for="access_token">GitHub Access Token</label></th>
|
||||
<td>
|
||||
<input type="password" id="access_token" name="access_token" class="regular-text">
|
||||
<p class="description">
|
||||
To generate a Personal Access Token, go to
|
||||
<a href="https://github.com/settings/tokens" target="_blank">GitHub Settings > Developer settings > Personal access tokens</a>.
|
||||
Create a new token with the 'repo' scope for private repositories.
|
||||
</p>
|
||||
</td>
|
||||
</tr>
|
||||
<tr id="version_row" style="display: none;">
|
||||
<th scope="row"><label for="version">Version</label></th>
|
||||
<td><select id="version" name="version"></select></td>
|
||||
</tr>
|
||||
</table>
|
||||
<div id="plugin_status"></div>
|
||||
<?php submit_button('Install/Update Plugin', 'primary', 'install_update_plugin'); ?>
|
||||
</form>
|
||||
<div id="repo_preview" style="margin-top: 20px; padding: 10px; border: 1px solid #ccc; display: none;">
|
||||
<h2>Repository Preview</h2>
|
||||
<div id="repo_content"></div>
|
||||
|
||||
<div class="github-add-project-section">
|
||||
<h2>Neues Projekt hinzufügen</h2>
|
||||
<form method="post" action="" id="github-project-form">
|
||||
<table class="form-table">
|
||||
<tr>
|
||||
<th scope="row"><label for="project_name">Projektname</label></th>
|
||||
<td><input type="text" id="project_name" name="project_name" class="regular-text" placeholder="Mein GitHub Plugin"></td>
|
||||
</tr>
|
||||
<tr>
|
||||
<th scope="row"><label for="repo_url">GitHub Repository URL</label></th>
|
||||
<td><input type="text" id="repo_url" name="repo_url" class="regular-text" required placeholder="https://github.com/username/repo.git"></td>
|
||||
</tr>
|
||||
<tr>
|
||||
<th scope="row"><label for="is_private">Privates Repository?</label></th>
|
||||
<td><input type="checkbox" id="is_private" name="is_private"></td>
|
||||
</tr>
|
||||
<tr id="access_token_row" style="display: none;">
|
||||
<th scope="row"><label for="access_token">GitHub Access Token</label></th>
|
||||
<td>
|
||||
<input type="password" id="access_token" name="access_token" class="regular-text">
|
||||
<p class="description">
|
||||
To generate a Personal Access Token, go to
|
||||
<a href="https://github.com/settings/tokens" target="_blank">GitHub Settings > Developer settings > Personal access tokens</a>.
|
||||
Create a new token with the 'repo' scope for private repositories.
|
||||
</p>
|
||||
</td>
|
||||
</tr>
|
||||
<tr id="version_row" style="display: none;">
|
||||
<th scope="row"><label for="version">Version</label></th>
|
||||
<td><select id="version" name="version"></select></td>
|
||||
</tr>
|
||||
</table>
|
||||
<div id="plugin_status"></div>
|
||||
<?php submit_button('Installieren/Aktualisieren', 'primary', 'install_update_plugin', false); ?>
|
||||
<button type="button" id="save_project_btn" class="button github-save-project-btn" style="display:none;">Als Projekt speichern</button>
|
||||
</form>
|
||||
<div id="repo_preview" style="margin-top: 20px; padding: 10px; border: 1px solid #ccc; display: none;">
|
||||
<h3>Repository Preview</h3>
|
||||
<div id="repo_content"></div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<?php if (!empty($saved_projects)): ?>
|
||||
<h2>Gespeicherte Projekte</h2>
|
||||
<div class="github-projects-grid">
|
||||
<?php foreach ($saved_projects as $project): ?>
|
||||
<div class="github-project-card" data-project-id="<?php echo esc_attr($project['id']); ?>">
|
||||
<h3><?php echo esc_html($project['name']); ?></h3>
|
||||
<div class="github-project-info">
|
||||
<p><strong>Repository:</strong> <?php echo esc_html($project['repo_url']); ?></p>
|
||||
<p><strong>Version:</strong> <?php echo esc_html($project['version']); ?></p>
|
||||
<p><strong>Status:</strong> <?php echo $project['is_private'] ? 'Privat' : 'Öffentlich'; ?></p>
|
||||
<p><strong>Zuletzt synchronisiert:</strong> <?php echo esc_html($project['last_synced']); ?></p>
|
||||
</div>
|
||||
<div class="github-project-actions">
|
||||
<button class="github-sync-btn" data-project-id="<?php echo esc_attr($project['id']); ?>">
|
||||
Synchronisieren
|
||||
</button>
|
||||
<button class="github-delete-btn" data-project-id="<?php echo esc_attr($project['id']); ?>">
|
||||
Löschen
|
||||
</button>
|
||||
</div>
|
||||
<div class="github-sync-status" data-project-id="<?php echo esc_attr($project['id']); ?>"></div>
|
||||
</div>
|
||||
<?php endforeach; ?>
|
||||
</div>
|
||||
<?php else: ?>
|
||||
<div class="notice notice-info">
|
||||
<p>Keine gespeicherten Projekte vorhanden. Fügen Sie oben ein neues Projekt hinzu.</p>
|
||||
</div>
|
||||
<?php endif; ?>
|
||||
</div>
|
||||
<?php
|
||||
}
|
||||
|
|
@ -95,19 +285,55 @@ function install_update_github_plugin($repo_url, $access_token, $selected_versio
|
|||
|
||||
if ($is_update) {
|
||||
// Update existing plugin
|
||||
$update_command = "cd " . escapeshellarg($plugin_dir) . " && git fetch --all && git checkout " . escapeshellarg($selected_version);
|
||||
exec($update_command, $output, $return_var);
|
||||
// Update remote URL with access token if provided
|
||||
if (!empty($access_token)) {
|
||||
$auth_repo_url = str_replace('https://', "https://{$access_token}@", $repo_url);
|
||||
$set_url_command = "cd " . escapeshellarg($plugin_dir) . " && git remote set-url origin " . escapeshellarg($auth_repo_url) . " 2>&1";
|
||||
exec($set_url_command, $url_output, $url_return);
|
||||
}
|
||||
|
||||
if ($return_var !== 0) {
|
||||
wp_die('Failed to update the plugin. Error: ' . implode("\n", $output));
|
||||
// Validate version before checkout
|
||||
if (!empty($selected_version)) {
|
||||
$update_command = "cd " . escapeshellarg($plugin_dir) . " && git fetch --all && git checkout " . escapeshellarg($selected_version) . " 2>&1";
|
||||
exec($update_command, $output, $return_var);
|
||||
|
||||
if ($return_var !== 0) {
|
||||
// Reset remote URL to original (without token) for security
|
||||
if (!empty($access_token)) {
|
||||
$reset_url_command = "cd " . escapeshellarg($plugin_dir) . " && git remote set-url origin " . escapeshellarg($repo_url) . " 2>&1";
|
||||
exec($reset_url_command, $reset_output, $reset_return);
|
||||
}
|
||||
wp_die('Failed to update the plugin. Error: ' . implode("\n", $output));
|
||||
}
|
||||
} else {
|
||||
// If no version specified, just fetch and pull the default branch
|
||||
$update_command = "cd " . escapeshellarg($plugin_dir) . " && git fetch --all && git pull 2>&1";
|
||||
exec($update_command, $output, $return_var);
|
||||
|
||||
if ($return_var !== 0) {
|
||||
// Reset remote URL to original (without token) for security
|
||||
if (!empty($access_token)) {
|
||||
$reset_url_command = "cd " . escapeshellarg($plugin_dir) . " && git remote set-url origin " . escapeshellarg($repo_url) . " 2>&1";
|
||||
exec($reset_url_command, $reset_output, $reset_return);
|
||||
}
|
||||
wp_die('Failed to update the plugin. Error: ' . implode("\n", $output));
|
||||
}
|
||||
}
|
||||
|
||||
// Reset remote URL to original (without token) for security
|
||||
if (!empty($access_token)) {
|
||||
$reset_url_command = "cd " . escapeshellarg($plugin_dir) . " && git remote set-url origin " . escapeshellarg($repo_url) . " 2>&1";
|
||||
exec($reset_url_command, $reset_output, $reset_return);
|
||||
}
|
||||
} else {
|
||||
// Install new plugin
|
||||
$clone_command = "git clone ";
|
||||
if (!empty($access_token)) {
|
||||
$repo_url = str_replace('https://', "https://{$access_token}@", $repo_url);
|
||||
$repo_url_with_token = str_replace('https://', "https://{$access_token}@", $repo_url);
|
||||
$clone_command .= escapeshellarg($repo_url_with_token) . " " . escapeshellarg($plugin_dir);
|
||||
} else {
|
||||
$clone_command .= escapeshellarg($repo_url) . " " . escapeshellarg($plugin_dir);
|
||||
}
|
||||
$clone_command .= escapeshellarg($repo_url) . " " . escapeshellarg($plugin_dir);
|
||||
|
||||
exec($clone_command, $output, $return_var);
|
||||
|
||||
|
|
@ -115,6 +341,12 @@ function install_update_github_plugin($repo_url, $access_token, $selected_versio
|
|||
wp_die('Failed to clone the repository. Error: ' . implode("\n", $output));
|
||||
}
|
||||
|
||||
// Reset remote URL to original (without token) for security
|
||||
if (!empty($access_token)) {
|
||||
$reset_url_command = "cd " . escapeshellarg($plugin_dir) . " && git remote set-url origin " . escapeshellarg($repo_url) . " 2>&1";
|
||||
exec($reset_url_command, $reset_output, $reset_return);
|
||||
}
|
||||
|
||||
// Checkout the selected version
|
||||
if (!empty($selected_version)) {
|
||||
$checkout_command = "cd " . escapeshellarg($plugin_dir) . " && git checkout " . escapeshellarg($selected_version);
|
||||
|
|
@ -274,4 +506,124 @@ function check_plugin_status() {
|
|||
} else {
|
||||
wp_send_json_success(array('status' => 'not_installed'));
|
||||
}
|
||||
}
|
||||
|
||||
function save_github_project() {
|
||||
check_ajax_referer('github_installer_nonce', 'nonce');
|
||||
|
||||
if (!current_user_can('manage_options')) {
|
||||
wp_send_json_error('Insufficient permissions.');
|
||||
}
|
||||
|
||||
$project_data = array(
|
||||
'name' => sanitize_text_field($_POST['name']),
|
||||
'repo_url' => esc_url_raw($_POST['repo_url']),
|
||||
'is_private' => !empty($_POST['is_private']) && $_POST['is_private'] !== 'false' && $_POST['is_private'] !== '0',
|
||||
'access_token' => isset($_POST['access_token']) ? sanitize_text_field($_POST['access_token']) : '',
|
||||
'version' => sanitize_text_field($_POST['version'])
|
||||
);
|
||||
|
||||
if (empty($project_data['name']) || empty($project_data['repo_url'])) {
|
||||
wp_send_json_error('Name und Repository URL sind erforderlich.');
|
||||
}
|
||||
|
||||
$project_id = save_project($project_data);
|
||||
wp_send_json_success(array('message' => 'Projekt erfolgreich gespeichert!', 'project_id' => $project_id));
|
||||
}
|
||||
|
||||
function delete_github_project() {
|
||||
check_ajax_referer('github_installer_nonce', 'nonce');
|
||||
|
||||
if (!current_user_can('manage_options')) {
|
||||
wp_send_json_error('Insufficient permissions.');
|
||||
}
|
||||
|
||||
$project_id = sanitize_text_field($_POST['project_id']);
|
||||
|
||||
if (delete_project($project_id)) {
|
||||
wp_send_json_success('Projekt erfolgreich gelöscht!');
|
||||
} else {
|
||||
wp_send_json_error('Projekt konnte nicht gelöscht werden.');
|
||||
}
|
||||
}
|
||||
|
||||
function sync_github_project() {
|
||||
check_ajax_referer('github_installer_nonce', 'nonce');
|
||||
|
||||
if (!current_user_can('manage_options')) {
|
||||
wp_send_json_error('Insufficient permissions.');
|
||||
}
|
||||
|
||||
$project_id = sanitize_text_field($_POST['project_id']);
|
||||
$projects = get_saved_projects();
|
||||
|
||||
if (!isset($projects[$project_id])) {
|
||||
wp_send_json_error('Projekt nicht gefunden.');
|
||||
}
|
||||
|
||||
$project = $projects[$project_id];
|
||||
|
||||
// Perform the sync
|
||||
try {
|
||||
$repo_url = $project['repo_url'];
|
||||
$access_token = $project['access_token'];
|
||||
$version = $project['version'];
|
||||
|
||||
$repo_name = strtolower(basename(parse_url($repo_url, PHP_URL_PATH), '.git'));
|
||||
$plugin_dir = WP_PLUGIN_DIR . '/' . $repo_name;
|
||||
|
||||
if (!file_exists($plugin_dir)) {
|
||||
wp_send_json_error('Plugin ist nicht installiert. Bitte installieren Sie es zuerst über das Formular oben.');
|
||||
}
|
||||
|
||||
// Update remote URL with access token if private repository
|
||||
if ($project['is_private'] && !empty($access_token)) {
|
||||
$auth_repo_url = str_replace('https://', "https://{$access_token}@", $repo_url);
|
||||
$set_url_command = "cd " . escapeshellarg($plugin_dir) . " && git remote set-url origin " . escapeshellarg($auth_repo_url) . " 2>&1";
|
||||
exec($set_url_command, $url_output, $url_return);
|
||||
}
|
||||
|
||||
// Update existing plugin - validate version before checkout
|
||||
if (!empty($version)) {
|
||||
$update_command = "cd " . escapeshellarg($plugin_dir) . " && git fetch --all && git checkout " . escapeshellarg($version) . " 2>&1";
|
||||
exec($update_command, $output, $return_var);
|
||||
|
||||
if ($return_var !== 0) {
|
||||
// Reset remote URL to original (without token) for security
|
||||
if ($project['is_private'] && !empty($access_token)) {
|
||||
$reset_url_command = "cd " . escapeshellarg($plugin_dir) . " && git remote set-url origin " . escapeshellarg($repo_url) . " 2>&1";
|
||||
exec($reset_url_command, $reset_output, $reset_return);
|
||||
}
|
||||
wp_send_json_error('Synchronisierung fehlgeschlagen: ' . implode("\n", $output));
|
||||
}
|
||||
} else {
|
||||
// If no version specified, just fetch and pull the default branch
|
||||
$update_command = "cd " . escapeshellarg($plugin_dir) . " && git fetch --all && git pull 2>&1";
|
||||
exec($update_command, $output, $return_var);
|
||||
|
||||
if ($return_var !== 0) {
|
||||
// Reset remote URL to original (without token) for security
|
||||
if ($project['is_private'] && !empty($access_token)) {
|
||||
$reset_url_command = "cd " . escapeshellarg($plugin_dir) . " && git remote set-url origin " . escapeshellarg($repo_url) . " 2>&1";
|
||||
exec($reset_url_command, $reset_output, $reset_return);
|
||||
}
|
||||
wp_send_json_error('Synchronisierung fehlgeschlagen: ' . implode("\n", $output));
|
||||
}
|
||||
}
|
||||
|
||||
// Reset remote URL to original (without token) for security
|
||||
if ($project['is_private'] && !empty($access_token)) {
|
||||
$reset_url_command = "cd " . escapeshellarg($plugin_dir) . " && git remote set-url origin " . escapeshellarg($repo_url) . " 2>&1";
|
||||
exec($reset_url_command, $reset_output, $reset_return);
|
||||
}
|
||||
|
||||
// Update last_synced timestamp
|
||||
$project['last_synced'] = current_time('mysql');
|
||||
$projects[$project_id] = $project;
|
||||
update_option('github_installer_projects', $projects);
|
||||
|
||||
wp_send_json_success('Projekt erfolgreich synchronisiert!');
|
||||
} catch (Exception $e) {
|
||||
wp_send_json_error('Fehler bei der Synchronisierung: ' . $e->getMessage());
|
||||
}
|
||||
}
|
||||
|
|
@ -17,6 +17,15 @@ jQuery(document).ready(function() {
|
|||
previewTimer = setTimeout(updatePreviewAndVersions, 500);
|
||||
});
|
||||
|
||||
// Show "Save as Project" button when version is selected
|
||||
jQuery('#version').on('change', function() {
|
||||
if(jQuery(this).val()) {
|
||||
jQuery('#save_project_btn').show();
|
||||
} else {
|
||||
jQuery('#save_project_btn').hide();
|
||||
}
|
||||
});
|
||||
|
||||
function updatePreviewAndVersions() {
|
||||
previewRepo();
|
||||
getVersions();
|
||||
|
|
@ -78,22 +87,137 @@ jQuery(document).ready(function() {
|
|||
var versions = response.data;
|
||||
var versionSelect = jQuery('#version');
|
||||
versionSelect.empty();
|
||||
versionSelect.append(jQuery('<option></option>').attr('value', '').text('-- Wählen Sie eine Version --'));
|
||||
jQuery.each(versions, function(index, version) {
|
||||
versionSelect.append(jQuery('<option></option>').attr('value', version).text(version));
|
||||
});
|
||||
jQuery('#version_row').show();
|
||||
} else {
|
||||
jQuery('#version_row').hide();
|
||||
jQuery('#save_project_btn').hide();
|
||||
console.error('Failed to fetch versions:', response.data);
|
||||
}
|
||||
},
|
||||
error: function() {
|
||||
jQuery('#version_row').hide();
|
||||
jQuery('#save_project_btn').hide();
|
||||
console.error('An error occurred while fetching the repository versions.');
|
||||
}
|
||||
});
|
||||
} else {
|
||||
jQuery('#version_row').hide();
|
||||
jQuery('#save_project_btn').hide();
|
||||
}
|
||||
}
|
||||
|
||||
// Save project button handler
|
||||
jQuery('#save_project_btn').on('click', function(e) {
|
||||
e.preventDefault();
|
||||
|
||||
var projectName = jQuery('#project_name').val();
|
||||
var repoUrl = jQuery('#repo_url').val();
|
||||
var isPrivate = jQuery('#is_private').is(':checked');
|
||||
var accessToken = jQuery('#access_token').val();
|
||||
var version = jQuery('#version').val();
|
||||
|
||||
if (!projectName) {
|
||||
alert('Bitte geben Sie einen Projektnamen ein.');
|
||||
return;
|
||||
}
|
||||
|
||||
if (!repoUrl || !version) {
|
||||
alert('Bitte füllen Sie alle erforderlichen Felder aus.');
|
||||
return;
|
||||
}
|
||||
|
||||
jQuery.ajax({
|
||||
url: github_installer.ajax_url,
|
||||
type: 'POST',
|
||||
data: {
|
||||
action: 'save_github_project',
|
||||
nonce: github_installer.nonce,
|
||||
name: projectName,
|
||||
repo_url: repoUrl,
|
||||
is_private: isPrivate,
|
||||
access_token: accessToken,
|
||||
version: version
|
||||
},
|
||||
success: function(response) {
|
||||
if (response.success) {
|
||||
alert(response.data.message);
|
||||
location.reload();
|
||||
} else {
|
||||
alert('Fehler: ' + response.data);
|
||||
}
|
||||
},
|
||||
error: function() {
|
||||
alert('Ein Fehler ist beim Speichern des Projekts aufgetreten.');
|
||||
}
|
||||
});
|
||||
});
|
||||
|
||||
// Sync project button handler
|
||||
jQuery(document).on('click', '.github-sync-btn', function() {
|
||||
var projectId = jQuery(this).data('project-id');
|
||||
var button = jQuery(this);
|
||||
var statusDiv = jQuery('.github-sync-status[data-project-id="' + projectId + '"]');
|
||||
|
||||
button.prop('disabled', true);
|
||||
statusDiv.removeClass('success error').addClass('loading').text('Synchronisierung läuft...').show();
|
||||
|
||||
jQuery.ajax({
|
||||
url: github_installer.ajax_url,
|
||||
type: 'POST',
|
||||
data: {
|
||||
action: 'sync_github_project',
|
||||
nonce: github_installer.nonce,
|
||||
project_id: projectId
|
||||
},
|
||||
success: function(response) {
|
||||
button.prop('disabled', false);
|
||||
if (response.success) {
|
||||
statusDiv.removeClass('loading error').addClass('success').text(response.data);
|
||||
setTimeout(function() {
|
||||
location.reload();
|
||||
}, 1500);
|
||||
} else {
|
||||
statusDiv.removeClass('loading success').addClass('error').text('Fehler: ' + response.data);
|
||||
}
|
||||
},
|
||||
error: function() {
|
||||
button.prop('disabled', false);
|
||||
statusDiv.removeClass('loading success').addClass('error').text('Ein Fehler ist aufgetreten.');
|
||||
}
|
||||
});
|
||||
});
|
||||
|
||||
// Delete project button handler
|
||||
jQuery(document).on('click', '.github-delete-btn', function() {
|
||||
var projectId = jQuery(this).data('project-id');
|
||||
|
||||
if (!confirm('Möchten Sie dieses Projekt wirklich löschen?')) {
|
||||
return;
|
||||
}
|
||||
|
||||
jQuery.ajax({
|
||||
url: github_installer.ajax_url,
|
||||
type: 'POST',
|
||||
data: {
|
||||
action: 'delete_github_project',
|
||||
nonce: github_installer.nonce,
|
||||
project_id: projectId
|
||||
},
|
||||
success: function(response) {
|
||||
if (response.success) {
|
||||
alert(response.data);
|
||||
location.reload();
|
||||
} else {
|
||||
alert('Fehler: ' + response.data);
|
||||
}
|
||||
},
|
||||
error: function() {
|
||||
alert('Ein Fehler ist beim Löschen des Projekts aufgetreten.');
|
||||
}
|
||||
});
|
||||
});
|
||||
});
|
||||
Loading…
Add table
Add a link
Reference in a new issue