| 1 |
<?php |
| 2 |
class Meow_WPLR_Sync_Admin extends MeowKit_WPLR_Admin { |
| 3 |
protected $wplr; |
| 4 |
|
| 5 |
public static $logo = 'data:image/svg+xml;base64,PHN2ZyB2ZXJzaW9uPSIxIiB2aWV3Qm94PSIwIDAgMTY1IDE2NSIgeG1sbnM9Imh0dHA6Ly93d3cudzMub3JnLzIwMDAvc3ZnIj4KICA8c3R5bGU+CiAgICAuc3Qye2ZpbGw6IzgwNDYyNX0uc3Qze2ZpbGw6I2ZkYTk2MH0KICA8L3N0eWxlPgogIDxwYXRoIGQ9Ik03MiA3YTc2IDc2IDAgMCAxIDg0IDkxQTc1IDc1IDAgMSAxIDcyIDd6IiBmaWxsPSIjNGE2YjhjIi8+CiAgPHBhdGggZD0iTTQ4IDQ4YzIgNSAyIDEwIDUgMTQgNSA4IDEzIDE3IDIyIDIwbDEtMTBjMS0yIDMtMyA1LTNoMTNjMiAwIDQgMSA1IDNsMyA5IDQtMTBjMi0zIDYtMiA5LTJoMTFjMyAyIDMgNSAzIDhsMiAzN2MwIDMtMSA3LTQgOGgtMTJjLTIgMC0zLTItNS00LTEgMS0yIDMtNCAzLTUgMS05IDEtMTMtMS0zIDItNSAyLTkgMnMtOSAxLTEwLTNjLTItNC0xLTggMC0xMi04LTMtMTUtNy0yMi0xMi03LTctMTUtMTQtMjAtMjMtMy00LTUtOC01LTEzIDEtNCAzLTEwIDYtMTMgNC0zIDEyLTIgMTUgMnoiIGZpbGw9IiMxMDEwMTAiLz4KICA8cGF0aCBjbGFzcz0ic3QyIiBkPSJNNDMgNTFsNCAxMS02IDVoLTZjLTMtNS0zLTExIDAtMTYgMi0yIDYtMyA4IDB6Ii8+CiAgPHBhdGggY2xhc3M9InN0MyIgZD0iTTQ3IDYybDMgNmMwIDMgMCA0LTIgNnMtNCAyLTcgMmwtNi05aDZsNi01eiIvPgogIDxwYXRoIGNsYXNzPSJzdDIiIGQ9Ik01MCA2OGw4IDljLTMgMy01IDYtOSA4bC04LTljMyAwIDUgMCA3LTJzMy0zIDItNnoiLz4KICA8cGF0aCBkPSJNODIgNzRoMTJsNSAxOCAzIDExIDgtMjloMTNsMiA0MmgtOGwtMS0yLTEtMzEtMTAgMzItNyAxLTktMzMtMSAyOS0xIDRoLThsMy00MnoiIGZpbGw9IiNmZmYiLz4KICA8cGF0aCBjbGFzcz0ic3QzIiBkPSJNNTggNzdsNSA1Yy0xIDQtMiA4LTcgOGwtNy01YzQtMiA2LTUgOS04eiIvPgogIDxwYXRoIGNsYXNzPSJzdDIiIGQ9Ik02MyA4Mmw5IDUtNiA5LTEwLTZjNSAwIDYtNCA3LTh6Ii8+CiAgPHBhdGggY2xhc3M9InN0MyIgZD0iTTcyIDg3bDMgMS0xIDExLTgtMyA2LTEweiIvPgo8L3N2Zz4K'; |
| 6 |
|
| 7 |
public function __construct() { |
| 8 |
parent::__construct( WPLR_SYNC_PREFIX, WPLR_SYNC_ENTRY, WPLR_SYNC_DOMAIN ); |
| 9 |
if ( is_admin() ) { |
| 10 |
global $wplr; |
| 11 |
$this->wplr = $wplr; |
| 12 |
|
| 13 |
if ( current_user_can( 'upload_files' ) ) { |
| 14 |
add_action( 'show_user_profile', array ( $this, 'auth_token_field' ) ); |
| 15 |
add_action( 'edit_user_profile', array ( $this, 'auth_token_field' ) ); |
| 16 |
add_action( 'admin_menu', array( $this, 'admin_menu' ) ); |
| 17 |
} |
| 18 |
|
| 19 |
add_filter( 'wplr_meowapps_is_registered', array( $this, '' ) ); |
| 20 |
add_filter( 'media_row_actions', array( $this, 'media_row_actions' ), 10, 2 ); |
| 21 |
add_action( 'wp_ajax_wplrsync_generate_auth_token', array ( $this, 'ajax_generate_auth_token' ) ); |
| 22 |
add_action( 'wp_ajax_wplrsync_link', array( $wplr, 'wplrsync_link' ) ); |
| 23 |
add_action( 'wp_ajax_wplrsync_unlink', array( $wplr, 'wplrsync_unlink' ) ); |
| 24 |
add_action( 'wp_ajax_wplrsync_clean', array( $this, 'wplrsync_clean' ) ); |
| 25 |
add_action( 'wp_ajax_wplrsync_extensions_reset', array( $this, 'wplrsync_extensions_reset' ) ); |
| 26 |
add_action( 'wp_ajax_wplrsync_extensions_init', array( $this, 'wplrsync_extensions_init' ) ); |
| 27 |
add_action( 'wp_ajax_wplrsync_extensions_query', array( $this, 'wplrsync_extensions_query' ) ); |
| 28 |
add_action( 'add_meta_boxes', array( $this, 'add_format_warning_metabox' ) ); |
| 29 |
//if ( get_option( 'wplr_library_show_hierarchy', 'none' ) !== 'none' ) { |
| 30 |
$wplr_medialib = new Meow_WPLR_Sync_Explorer(); |
| 31 |
//} |
| 32 |
// Load the scripts only if they are needed by the current screen |
| 33 |
$uri = $_SERVER['REQUEST_URI']; |
| 34 |
$page = isset( $_GET["page"] ) ? $_GET["page"] : null; |
| 35 |
$is_media_library = preg_match( '/wp\-admin\/upload\.php/', $uri ); |
| 36 |
$is_wplr_sync_screen = in_array( $page, [ 'wplr_sync_settings', 'wplr_sync_dashboard' ] ); |
| 37 |
$is_meowapps_dashboard = $page === 'meowapps-main-menu'; |
| 38 |
//if ( $is_meowapps_dashboard || $is_wplr_sync_screen || $is_media_library ) { |
| 39 |
add_action( 'admin_enqueue_scripts', array( $this, 'admin_enqueue_scripts' ) ); |
| 40 |
//} |
| 41 |
} |
| 42 |
} |
| 43 |
|
| 44 |
private function wp_ajax_auth_check( $action ) { |
| 45 |
$nonce = apply_filters( 'wplr_sync_ajax_nonce', check_ajax_referer( $action ) ); |
| 46 |
if ( !$nonce ) { |
| 47 |
wp_send_json_error( 'Invalid nonce' ); |
| 48 |
} |
| 49 |
|
| 50 |
$user_can = apply_filters( 'wplr_sync_ajax_user_can', current_user_can( 'manage_options' ) ); |
| 51 |
if ( !$user_can ) { |
| 52 |
wp_send_json_error( 'You do not have sufficient permissions to perform this action.' ); |
| 53 |
} |
| 54 |
} |
| 55 |
|
| 56 |
function admin_enqueue_scripts() { |
| 57 |
|
| 58 |
// Load the scripts |
| 59 |
$physical_file = WPLR_SYNC_PATH . '/app/index.js'; |
| 60 |
$cache_buster = file_exists( $physical_file ) ? filemtime( $physical_file ) : WPLR_SYNC_VERSION; |
| 61 |
wp_register_script( 'pEngine-vendor', WPLR_SYNC_URL . 'app/vendor.js', |
| 62 |
['wp-element', 'wp-i18n'], $cache_buster |
| 63 |
); |
| 64 |
wp_register_script( 'pEngine', WPLR_SYNC_URL . 'app/index.js', |
| 65 |
['pEngine-vendor', 'wp-i18n'], $cache_buster |
| 66 |
); |
| 67 |
wp_set_script_translations( 'pEngine', 'wplr-sync' ); |
| 68 |
wp_enqueue_script('pEngine' ); |
| 69 |
|
| 70 |
// Load the fonts |
| 71 |
wp_register_style( 'meow-neko-ui-lato-font', '//fonts.googleapis.com/css2?family=Lato:wght@100;300;400;700;900&display=swap'); |
| 72 |
wp_enqueue_style( 'meow-neko-ui-lato-font' ); |
| 73 |
|
| 74 |
global $wplr; |
| 75 |
$screen = get_current_screen(); |
| 76 |
$collections = $wplr->read_collections_recursively(); |
| 77 |
|
| 78 |
// Localize and options |
| 79 |
$col_id = isset($_GET['col_id']) ? (int)$_GET['col_id'] : 0; |
| 80 |
wp_localize_script( 'pEngine', 'pEngine', array_merge( [ |
| 81 |
'api_url' => rest_url( 'wplr-sync/v1' ), |
| 82 |
'rest_url' => rest_url(), |
| 83 |
'plugin_url' => WPLR_SYNC_URL, |
| 84 |
'prefix' => WPLR_SYNC_PREFIX, |
| 85 |
'domain' => WPLR_SYNC_DOMAIN, |
| 86 |
'is_pro' => true, |
| 87 |
'is_registered' => true, |
| 88 |
'rest_nonce' => wp_create_nonce( 'wp_rest' ), |
| 89 |
'hierarchy' => $collections, |
| 90 |
'isMediaLibrary' => $screen->base === 'upload', |
| 91 |
'col_id' => $col_id, |
| 92 |
'media_library' => get_option( 'wplr_media_library' ), |
| 93 |
'media_modals' => get_option( 'wplr_media_modals' ), |
| 94 |
], $this->get_all_options() ) ); |
| 95 |
} |
| 96 |
|
| 97 |
function is_registered() { |
| 98 |
return true; |
| 99 |
} |
| 100 |
|
| 101 |
function list_options() { |
| 102 |
return array( |
| 103 |
'wplr_use_taken_date' => false, |
| 104 |
'wplr_upload_folder' => false, |
| 105 |
'wplr_filename_accents' => false, |
| 106 |
'wplr_enable_keywords' => false, |
| 107 |
'wplr_sync_keywords' => '', |
| 108 |
'wplr_library_show_hierarchy' => 'none', |
| 109 |
'wplr_public_api' => false, |
| 110 |
'wr2x_big_image_size_threshold' => false, |
| 111 |
'wplr_debugging_enabled' => false, |
| 112 |
'wplr_catch_errors' => false, |
| 113 |
'wplr_check_same_file' => false, |
| 114 |
'wplr_debuglogs' => false, |
| 115 |
'wplr_hide_extensions' => false, |
| 116 |
'wplr_protocol' => false, |
| 117 |
'wplr_library_show_filters' => false, |
| 118 |
'wplr_auth_token' => false, |
| 119 |
'wplr_qr' => null, |
| 120 |
'wplr_user_token' => null, |
| 121 |
'sync_keywords_options' => [], |
| 122 |
'troubles_issues' => [], |
| 123 |
'extensions' => [], |
| 124 |
'wplr_media_organizer' => false, |
| 125 |
'wplr_media_library' => false, |
| 126 |
'wplr_media_modals' => false, |
| 127 |
); |
| 128 |
} |
| 129 |
|
| 130 |
/** |
| 131 |
* Generates a new Public API auth token, stores it as a transient and returns it. |
| 132 |
* @return string The new token |
| 133 |
*/ |
| 134 |
function generate_public_api_token() { |
| 135 |
$token = str_replace( '|', '#', wp_generate_password( 12, false, false ) ); |
| 136 |
set_transient( 'wplr_auth_token', $token, YEAR_IN_SECONDS ); |
| 137 |
return $token; |
| 138 |
} |
| 139 |
|
| 140 |
/** |
| 141 |
* Builds the QR payload (home url + token) used by the Public API. |
| 142 |
* @param string $token |
| 143 |
* @return string |
| 144 |
*/ |
| 145 |
function get_public_api_qr( $token ) { |
| 146 |
$home_url = function_exists( 'pll_home_url' ) ? pll_home_url() : get_home_url(); |
| 147 |
return $home_url . '|' . $token; |
| 148 |
} |
| 149 |
|
| 150 |
/** |
| 151 |
* Returns the personal auth token of the current user (used to authenticate as |
| 152 |
* this WordPress user through the API). Generates one if it does not exist yet. |
| 153 |
* @return string|null |
| 154 |
*/ |
| 155 |
function get_user_token() { |
| 156 |
$user_id = get_current_user_id(); |
| 157 |
if ( !$user_id ) { |
| 158 |
return null; |
| 159 |
} |
| 160 |
$token = get_user_meta( $user_id, 'wplr_auth_token', true ); |
| 161 |
if ( empty( $token ) ) { |
| 162 |
global $wplr; |
| 163 |
try { |
| 164 |
$token = $wplr->generate_auth_token( $user_id ); |
| 165 |
} |
| 166 |
catch ( Exception $e ) { |
| 167 |
$token = null; |
| 168 |
} |
| 169 |
} |
| 170 |
return $token; |
| 171 |
} |
| 172 |
|
| 173 |
function get_all_options() { |
| 174 |
// sync_keywords_options |
| 175 |
$taxonomies = get_object_taxonomies( 'attachment' ); |
| 176 |
array_unshift( $taxonomies, "" ); |
| 177 |
|
| 178 |
// Troubleshooting (Potential issues) |
| 179 |
$troubles = new Meow_WPLR_Sync_Troubleshoot(); |
| 180 |
$issues = $troubles->issues(); |
| 181 |
|
| 182 |
// Extensions |
| 183 |
$extensions = apply_filters( 'wplr_extensions', [] ); |
| 184 |
|
| 185 |
// Public API |
| 186 |
$public_api = get_option( 'wplr_public_api', false ); |
| 187 |
$wplr_auth_token = get_transient( 'wplr_auth_token' ); |
| 188 |
$wplr_qr = null; |
| 189 |
if ( $public_api ) { |
| 190 |
if ( $wplr_auth_token === false ) { |
| 191 |
$wplr_auth_token = $this->generate_public_api_token(); |
| 192 |
} |
| 193 |
$wplr_qr = $this->get_public_api_qr( $wplr_auth_token ); |
| 194 |
} |
| 195 |
elseif ( $wplr_auth_token !== false ) { |
| 196 |
delete_transient( 'wplr_auth_token' ); |
| 197 |
} |
| 198 |
|
| 199 |
$options = $this->list_options(); |
| 200 |
$current_options = array(); |
| 201 |
foreach ( $options as $option => $default ) { |
| 202 |
if ( $option === 'wplr_public_api' ) { |
| 203 |
$current_options[$option] = $public_api; |
| 204 |
} elseif ( $option === 'wplr_auth_token' ) { |
| 205 |
$current_options[$option] = $wplr_auth_token; |
| 206 |
} elseif ( $option === 'wplr_qr' ) { |
| 207 |
$current_options[$option] = $wplr_qr; |
| 208 |
} elseif ( $option === 'wplr_user_token' ) { |
| 209 |
$current_options[$option] = $this->get_user_token(); |
| 210 |
} elseif ( $option === 'sync_keywords_options' ) { |
| 211 |
$current_options[$option] = $taxonomies; |
| 212 |
} elseif ( $option === 'troubles_issues' ) { |
| 213 |
$current_options[$option] = $issues; |
| 214 |
} elseif ( $option === 'extensions' ) { |
| 215 |
$current_options[$option] = $extensions; |
| 216 |
} else { |
| 217 |
$current_options[$option] = get_option( $option, $default ); |
| 218 |
} |
| 219 |
} |
| 220 |
return $current_options; |
| 221 |
} |
| 222 |
|
| 223 |
/** |
| 224 |
* Outputs the auth token generator UI |
| 225 |
* @param $user |
| 226 |
*/ |
| 227 |
function auth_token_field( $user ) { |
| 228 |
?> |
| 229 |
<table class="form-table"> |
| 230 |
<tr> |
| 231 |
<th><?php _e( 'Token for Photo Engine', 'wplr-sync' ); ?></th> |
| 232 |
<td id="wplr-auth-token-generator"> |
| 233 |
<button class="button"><?php _e( 'Generate Token', 'wplr-sync' ); ?></button> |
| 234 |
<?php $token = get_user_meta( $user->ID, 'wplr_auth_token', true ); ?> |
| 235 |
<p class="description<?php if ( !$token ) echo ' no-token hidden'; ?>">Your token is <var class="token"><?php echo esc_html( $token ); ?></var></p> |
| 236 |
</td> |
| 237 |
</tr> |
| 238 |
</table> |
| 239 |
<script> |
| 240 |
(function ($) { |
| 241 |
var wrap = $('#wplr-auth-token-generator') |
| 242 |
wrap.find('button').on('click', function (ev) { |
| 243 |
ev.preventDefault() |
| 244 |
|
| 245 |
var $this = $(this) // The button itself |
| 246 |
if ($this.prop('disabled')) return false |
| 247 |
$this.prop('disabled', true) |
| 248 |
|
| 249 |
$.ajax(ajaxurl, { |
| 250 |
method: 'POST', |
| 251 |
dataType: 'json', |
| 252 |
data: { |
| 253 |
_ajax_nonce: '<?php echo wp_create_nonce( 'wplrsync_generate_auth_token' ); ?>', |
| 254 |
action: 'wplrsync_generate_auth_token' |
| 255 |
} |
| 256 |
|
| 257 |
}).always(function () { |
| 258 |
$this.prop('disabled', false) |
| 259 |
|
| 260 |
}).fail(function (err) { |
| 261 |
var msg = '<?php _e( 'Failed to generate an auth token due to the following reason:', 'wplr-sync' ); ?>' + '\n' |
| 262 |
msg += '"' + err.responseJSON.data + '"' + '\n' |
| 263 |
msg += 'Status: ' + err.status + ' ' + err.statusText + '\n' |
| 264 |
console.error(msg) |
| 265 |
// TODO: Show the error message on the front |
| 266 |
|
| 267 |
}).done(function (result) { |
| 268 |
var token = result.data.newToken |
| 269 |
wrap.find('var.token').text(token) |
| 270 |
wrap.find('.no-token.hidden').removeClass('hidden') |
| 271 |
}) |
| 272 |
}) |
| 273 |
})(jQuery) |
| 274 |
</script> |
| 275 |
<style> |
| 276 |
#wplr-auth-token-generator var.token { |
| 277 |
font-style: normal; |
| 278 |
font-family: monospace; |
| 279 |
color: green; |
| 280 |
} |
| 281 |
</style> |
| 282 |
<?php |
| 283 |
} |
| 284 |
|
| 285 |
/** |
| 286 |
* Generates an auth token via ajax |
| 287 |
* @uses $_POST['action'] |
| 288 |
* @uses $_POST['userId'] |
| 289 |
*/ |
| 290 |
function ajax_generate_auth_token() { |
| 291 |
if ( !check_ajax_referer( $_POST['action'] ) ) { |
| 292 |
wp_send_json_error( __( 'Invalid nonce', 'wplr-sync' ), 403 ); |
| 293 |
} |
| 294 |
$userId = get_current_user_id(); |
| 295 |
$user = get_userdata( $userId ); |
| 296 |
if ( !$user ) { |
| 297 |
wp_send_json_error( __( 'You have to be logged in', 'wplr-sync' ), 401 ); |
| 298 |
} |
| 299 |
try { |
| 300 |
$token = $this->wplr->generate_auth_token( $userId ); |
| 301 |
} |
| 302 |
catch ( Exception $e ) { |
| 303 |
wp_send_json_error( __( 'Failed to save the auth token to DB', 'wplr-sync' ), 500 ); // I/O failure |
| 304 |
} |
| 305 |
wp_send_json_success( array ( 'newToken' => $token ) ); |
| 306 |
} |
| 307 |
|
| 308 |
function common_url( $file ) { |
| 309 |
return plugin_dir_url( __FILE__ ) . ( '\/common\/' . $file ); |
| 310 |
} |
| 311 |
|
| 312 |
function media_row_actions( $actions, $post ) { |
| 313 |
global $current_screen; |
| 314 |
if ( 'upload' != $current_screen->id ) { |
| 315 |
return $actions; |
| 316 |
} |
| 317 |
global $wpdb; |
| 318 |
$table_name = $wpdb->prefix . "lrsync"; |
| 319 |
$res = $wpdb->get_var( $wpdb->prepare( "SELECT COUNT(*) FROM $table_name WHERE wp_id = %d", $post->ID ) ); |
| 320 |
if ( !empty( $res ) && isset( $actions['trash'] ) ) |
| 321 |
$actions['trash'] = "Trash"; |
| 322 |
return $actions; |
| 323 |
} |
| 324 |
|
| 325 |
function admin_menu() { |
| 326 |
$hide_extensions = get_option( 'wplr_hide_extensions' ) && !get_option( 'wplr_debugging_enabled' ); |
| 327 |
|
| 328 |
// -- Debugging |
| 329 |
add_settings_section( 'wplr_settings_debug', null, null, 'wplr-settings-menu-debug' ); |
| 330 |
add_settings_field( 'wplr_debugging_enabled', __( 'Debugging', 'wplr-sync' ), |
| 331 |
array( $this, 'admin_debugging_callback' ),'wplr-settings-menu-debug', 'wplr_settings_debug', |
| 332 |
array( "Enable" ) ); |
| 333 |
add_settings_field( 'wplr_catch_errors', __( 'Catch Errors', 'wplr-sync' ), |
| 334 |
array( $this, 'admin_catch_errors_callback' ),'wplr-settings-menu-debug', 'wplr_settings_debug', |
| 335 |
array( "Enable" ) ); |
| 336 |
add_settings_field( 'wplr_check_same_file', __( 'Avoid Double Processing', 'wplr-sync' ), |
| 337 |
array( $this, 'admin_check_same_file_callback' ),'wplr-settings-menu-debug', 'wplr_settings_debug', |
| 338 |
array( "Enable (BETA)" ) ); |
| 339 |
add_settings_field( 'wplr_debuglogs', __( 'Advanced Logs', 'wplr-sync' ), |
| 340 |
array( $this, 'admin_debuglogs_callback' ), 'wplr-settings-menu-debug', 'wplr_settings_debug', |
| 341 |
array( "Enable" ) ); |
| 342 |
register_setting( 'wplr-settings-debug', 'wplr_library_show_hierarchy' ); |
| 343 |
register_setting( 'wplr-settings-debug', 'wplr_debuglogs' ); |
| 344 |
register_setting( 'wplr-settings-debug', 'wplr_catch_errors' ); |
| 345 |
register_setting( 'wplr-settings-debug', 'wplr_debugging_enabled' ); |
| 346 |
register_setting( 'wplr-settings-debug', 'wplr_check_same_file' ); |
| 347 |
register_setting( 'wplr-settings-debug', 'wplr_public_api' ); |
| 348 |
|
| 349 |
add_submenu_page( 'meowapps-main-menu', 'Photo Engine', 'Photo Engine', 'manage_options', |
| 350 |
'wplr_sync_settings', array( $this, 'admin_settings' ) ); |
| 351 |
|
| 352 |
// Debug |
| 353 |
if ( get_option( 'wplr_debugging_enabled' ) ) |
| 354 |
add_submenu_page( 'meowapps-main-menu', |
| 355 |
__( 'Photo Engine Debug', 'wplr-sync' ), |
| 356 |
__( 'Photo Engine Debug', 'wplr-sync' ), 'manage_options', |
| 357 |
'wplrsync-debug-menu', array( $this, 'admin_debug' ) ); |
| 358 |
} |
| 359 |
|
| 360 |
function admin_settings() { |
| 361 |
echo '<div id="wplr-sync-admin-settings"></div>'; |
| 362 |
} |
| 363 |
|
| 364 |
/* |
| 365 |
OPTIONS |
| 366 |
*/ |
| 367 |
|
| 368 |
function wplrsync_clean() { |
| 369 |
$this->wp_ajax_auth_check( 'wp_ajax_wplrsync_clean' ); |
| 370 |
|
| 371 |
global $wpdb; |
| 372 |
$tbl_m = $wpdb->prefix . 'lrsync'; |
| 373 |
$tbl_r = $wpdb->prefix . 'lrsync_relations'; |
| 374 |
$tbl_c = $wpdb->prefix . 'lrsync_collections'; |
| 375 |
$tbl_mt = $wpdb->prefix . 'lrsync_meta'; |
| 376 |
try { |
| 377 |
do_action( 'wplr_clean' ); |
| 378 |
$wpdb->query( "DELETE FROM $tbl_m WHERE wp_id NOT IN (SELECT ID FROM $wpdb->posts WHERE post_type = 'attachment')" ); |
| 379 |
$wpdb->query( "DELETE FROM $tbl_r WHERE wp_id NOT IN (SELECT ID FROM $wpdb->posts WHERE post_type = 'attachment')" ); |
| 380 |
$wpdb->query( "DELETE FROM $tbl_r WHERE wp_col_id NOT IN (SELECT wp_col_id FROM $tbl_c)" ); |
| 381 |
$wpdb->query( "DELETE FROM $tbl_mt WHERE name = 'media_tag' AND id NOT IN (SELECT ID FROM $wpdb->posts WHERE post_type = 'attachment')" ); |
| 382 |
echo json_encode( array( 'success' => true ) ); |
| 383 |
} |
| 384 |
catch ( Exception $e ) { |
| 385 |
error_log( print_r( $e, true ) ); |
| 386 |
echo json_encode( array( 'success' => false, 'message' => "An exception was caught and written in the PHP error logs." ) ); |
| 387 |
} |
| 388 |
die(); |
| 389 |
} |
| 390 |
|
| 391 |
|
| 392 |
|
| 393 |
function wplrsync_extensions_reset() { |
| 394 |
$this->wp_ajax_auth_check( 'wp_ajax_wplrsync_extensions_reset' ); |
| 395 |
|
| 396 |
try { |
| 397 |
do_action( 'wplr_reset' ); |
| 398 |
wp_send_json_success(); |
| 399 |
} catch ( Exception $e ) { |
| 400 |
error_log( print_r( $e, true ) ); |
| 401 |
wp_send_json_error( 'An exception was caught and written in the PHP error logs.' ); |
| 402 |
} |
| 403 |
} |
| 404 |
|
| 405 |
function wplrsync_extensions_query() { |
| 406 |
$this->wp_ajax_auth_check( 'wp_ajax_wplrsync_extensions_query' ); |
| 407 |
|
| 408 |
try { |
| 409 |
global $wplr; |
| 410 |
$task = $_POST['task']; |
| 411 |
if ( $task['action'] == 'add_collection' ) { |
| 412 |
if ( $task['is_folder'] ) |
| 413 |
do_action( 'wplr_create_folder', (int)$task['wp_col_id'], (int)$task['wp_folder_id'], array( 'name' => $task['name'] ) ); |
| 414 |
else |
| 415 |
do_action( 'wplr_create_collection', (int)$task['wp_col_id'], (int)$task['wp_folder_id'], array( 'name' => $task['name'] ) ); |
| 416 |
} |
| 417 |
else if ( $task['action'] == 'remove_collection' ) { |
| 418 |
if ( $task['is_folder'] ) |
| 419 |
do_action( 'wplr_remove_folder', (int)$task['wp_col_id'] ); |
| 420 |
else |
| 421 |
do_action( 'wplr_remove_collection', (int)$task['wp_col_id'] ); |
| 422 |
} |
| 423 |
else if ( $task['action'] == 'add_media' ) |
| 424 |
do_action( 'wplr_add_media_to_collection', (int)$task['wp_id'], (int)$task['wp_col_id'] ); |
| 425 |
else if ( $task['action'] == 'remove_media' ) |
| 426 |
do_action( 'wplr_remove_media_from_collection', (int)$task['wp_id'], (int)$task['wp_col_id'] ); |
| 427 |
else if ( $task['action'] == 'add_tag' ) { |
| 428 |
$pTagParent = $wplr->get_meta( 'tag_parent', (int)$task['id'] ); |
| 429 |
do_action( 'wplr_add_tag', (int)$task['id'], $task['name'], $pTagParent ); |
| 430 |
} |
| 431 |
else if ( $task['action'] == 'remove_tag' ) |
| 432 |
do_action( 'wplr_remove_tag', (int)$task['id'] ); |
| 433 |
else if ( $task['action'] == 'update_tag' ) |
| 434 |
do_action( 'wplr_update_tag', (int)$task['id'], $task['name'], (int)$task['parent'] ); |
| 435 |
else if ( $task['action'] == 'add_media_tag' ) |
| 436 |
do_action( 'wplr_add_media_tag', (int)$task['wp_id'], (int)$task['id'] ); |
| 437 |
else if ( $task['action'] == 'remove_media_tag' ) |
| 438 |
do_action( 'wplr_remove_media_tag', (int)$task['wp_id'], (int)$task['id'] ); |
| 439 |
|
| 440 |
echo json_encode( array( 'success' => true ) ); |
| 441 |
} |
| 442 |
catch ( Exception $e ) { |
| 443 |
error_log( print_r( $e, true ) ); |
| 444 |
echo json_encode( array( 'success' => false, 'message' => "An exception was caught and written in the PHP error logs." ) ); |
| 445 |
} |
| 446 |
die(); |
| 447 |
} |
| 448 |
|
| 449 |
function wplrsync_extensions_init() { |
| 450 |
$this->wp_ajax_auth_check( 'wp_ajax_wplrsync_extensions_init' ); |
| 451 |
|
| 452 |
global $wpdb, $wplr; |
| 453 |
$isRemoval = isset( $_POST['isRemoval'] ) && $_POST['isRemoval'] == 1; |
| 454 |
$tbl_m = $wpdb->prefix . 'lrsync'; |
| 455 |
$tbl_r = $wpdb->prefix . 'lrsync_relations'; |
| 456 |
$tbl_t = $wpdb->prefix . 'lrsync_meta'; |
| 457 |
|
| 458 |
$tasks = array(); |
| 459 |
|
| 460 |
// Tags |
| 461 |
$tags = $wpdb->get_results( $wpdb->prepare( "SELECT id as id, value as name FROM $tbl_t WHERE name = %s", 'tag_name' ), ARRAY_A ); |
| 462 |
foreach ( $tags as $tag ) |
| 463 |
array_push( $tasks, array_merge( array( 'action' => $isRemoval ? 'remove_tag' : 'add_tag' ), $tag ) ); |
| 464 |
|
| 465 |
// Tag's Parents |
| 466 |
if ( !$isRemoval ) { |
| 467 |
$tags = $wpdb->get_results( $wpdb->prepare( "SELECT m1.id as id, m1.value as name, m2.value as parent |
| 468 |
FROM $tbl_t m1 |
| 469 |
JOIN $tbl_t m2 ON m2.id = m1.id AND m2.name = %s |
| 470 |
WHERE m1.name = %s", 'tag_parent', 'tag_name' ), ARRAY_A ); |
| 471 |
|
| 472 |
foreach ( $tags as $tag ) |
| 473 |
array_push( $tasks, array_merge( array( 'action' => 'update_tag' ), $tag ) ); |
| 474 |
} |
| 475 |
|
| 476 |
// Collections |
| 477 |
$collections = $wplr->read_collections_recursively( null, array(), $isRemoval ); |
| 478 |
$tasks = array_merge( $tasks, $collections ); |
| 479 |
|
| 480 |
// Photos |
| 481 |
foreach ( $collections as $c ) { |
| 482 |
if ( !$c['is_folder'] ) { |
| 483 |
$photos = $wpdb->get_results( $wpdb->prepare( "SELECT wp_id, wp_col_id, sort FROM $tbl_r WHERE wp_col_id = %d ORDER BY sort", $c['wp_col_id'] ), ARRAY_A ); |
| 484 |
foreach ( $photos as $p ) |
| 485 |
array_push( $tasks, array_merge( array( 'action' => $isRemoval ? 'remove_media' : 'add_media' ), $p ) ); |
| 486 |
} |
| 487 |
}; |
| 488 |
|
| 489 |
// Media Tags |
| 490 |
$tags = $wpdb->get_results( $wpdb->prepare( " |
| 491 |
SELECT id as wp_id, value as id |
| 492 |
FROM $tbl_t |
| 493 |
WHERE name = %s", 'media_tag' ), ARRAY_A ); |
| 494 |
foreach ( $tags as $tag ) |
| 495 |
array_push( $tasks, array_merge( array( 'action' => $isRemoval ? 'remove_media_tag' : 'add_media_tag' ), $tag ) ); |
| 496 |
echo json_encode( array( 'success' => true, 'data' => $isRemoval ? $tasks : array_reverse( $tasks ) ) ); |
| 497 |
die(); |
| 498 |
} |
| 499 |
|
| 500 |
function admin_debugging_callback( $args ) { |
| 501 |
$html = '<input type="checkbox" id="wplr_debugging_enabled" name="wplr_debugging_enabled" value="1" ' . |
| 502 |
checked( 1, get_option( 'wplr_debugging_enabled' ), false ) . '/>'; |
| 503 |
$html .= '<label for="wplr_debugging_enabled"> ' . $args[0] . '</label><br>'; |
| 504 |
$html .= '<span class="description">' . |
| 505 |
__( 'Add a Debugging menu in Photo Engine. For advanced users only.', 'wplr-sync' ) . '</span>'; |
| 506 |
echo $html; |
| 507 |
} |
| 508 |
|
| 509 |
function admin_catch_errors_callback( $args ) { |
| 510 |
$html = '<input type="checkbox" id="wplr_catch_errors" name="wplr_catch_errors" value="1" ' . |
| 511 |
checked( 1, get_option( 'wplr_catch_errors' ), false ) . '/>'; |
| 512 |
$html .= '<label for="wplr_catch_errors"> ' . $args[0] . '</label><br>'; |
| 513 |
$html .= '<span class="description">' . |
| 514 |
__( 'Errors (from other plugins, themes, etc) happening during the Photo Engine process will be caught to avoid operations to fail.', 'wplr-sync' ) . '</span>'; |
| 515 |
echo $html; |
| 516 |
} |
| 517 |
|
| 518 |
function admin_check_same_file_callback( $args ) { |
| 519 |
$html = '<input type="checkbox" id="wplr_check_same_file" name="wplr_check_same_file" value="1" ' . |
| 520 |
checked( 1, get_option( 'wplr_check_same_file' ), false ) . '/>'; |
| 521 |
$html .= '<label for="wplr_check_same_file"> ' . $args[0] . '</label><br>'; |
| 522 |
$html .= '<span class="description">' . |
| 523 |
__( 'Avoid processing if the new file is the same as the old one, to avoid thumbnails to be generated again, optimizers, etc.', 'wplr-sync' ) . '</span>'; |
| 524 |
echo $html; |
| 525 |
} |
| 526 |
|
| 527 |
function admin_debuglogs_callback( $args ) { |
| 528 |
$clearlogs = isset ( $_GET[ 'clearlogs' ] ) ? $_GET[ 'clearlogs' ] : 0; |
| 529 |
if ( $clearlogs ) { |
| 530 |
if ( file_exists( plugin_dir_path( __FILE__ ) . '/wplr-sync.log' ) ) { |
| 531 |
unlink( plugin_dir_path( __FILE__ ) . '/wplr-sync.log' ); |
| 532 |
} |
| 533 |
} |
| 534 |
$html = '<input type="checkbox" id="wplr_debuglogs" name="wplr_debuglogs" value="1" ' . |
| 535 |
checked( 1, get_option( 'wplr_debuglogs' ), false ) . '/>'; |
| 536 |
$html .= '<label for="wplr_debuglogs"> ' . $args[0] . '</label><br>'; |
| 537 |
$html .= '<span class="description">' . __( 'Create an internal log file. For advanced users only.', 'wplr-sync' ); |
| 538 |
if ( file_exists( plugin_dir_path( __FILE__ ) . '/wplr-sync.log' ) ) { |
| 539 |
$html .= sprintf( __( '<br />The <a target="_blank" href="%s/wplr-sync.log">log file</a> is available. You can also <a href="?page=wplr-main-menu&clearlogs=true">clear</a> it.', 'wplr-sync' ), plugin_dir_url( __FILE__ ) ); |
| 540 |
} |
| 541 |
$html .= '</span>'; |
| 542 |
echo $html; |
| 543 |
} |
| 544 |
|
| 545 |
function display_hierarchy( $action ) { |
| 546 |
$mode = isset( $_POST['action'] ) && $action == "keywords" ? 'keywords' : 'hierarchy'; |
| 547 |
$delete_collection = isset( $_POST['delete_collection'] ) ? $_POST['delete_collection'] : null; |
| 548 |
$delete_keyword = isset( $_POST['delete_keyword'] ) ? $_POST['delete_keyword'] : null; |
| 549 |
$hasDeleted = false; |
| 550 |
|
| 551 |
if ( $delete_collection ) { |
| 552 |
global $wplr; |
| 553 |
$wplr->delete_collection( $delete_collection ); |
| 554 |
$hasDeleted = true; |
| 555 |
} |
| 556 |
if ( $delete_keyword ) { |
| 557 |
global $wplr; |
| 558 |
$wplr->delete_keyword( $delete_keyword ); |
| 559 |
$hasDeleted = true; |
| 560 |
} |
| 561 |
|
| 562 |
echo "<br /><br />"; |
| 563 |
$hierarchy = $mode == 'keywords' ? $this->wplr->get_keywords_hierarchy() : $this->wplr->get_hierarchy(); |
| 564 |
|
| 565 |
function display_internal_hierarchy( $hierarchy, $level = 0, $mode = '', $hasDeleted = false ) { |
| 566 |
global $wpdb; |
| 567 |
$tbl_r = $wpdb->prefix . 'lrsync_relations'; |
| 568 |
$page = empty( $_GET['page'] ) ? 'wplr-collections-tags-menu' : $_GET['page']; |
| 569 |
echo '<div class="hierarchy-level-' . $level . '">'; |
| 570 |
if ( $level > 0 ) |
| 571 |
echo '<div style="margin-left: 10px; border-left: 1px dotted gray; padding-left: 10px;">'; |
| 572 |
foreach ( $hierarchy as $c ) { |
| 573 |
|
| 574 |
if ( $mode == 'keywords' ) { |
| 575 |
echo '<div class="wplr-elem wplr-keyword" wplr-elem-type="keyword" wplr-elem-id="' . |
| 576 |
$c['id'] . '" wplr-elem-name="' . $c['name'] . '"><span class="dashicons dashicons-carrot"></span> <b>' . |
| 577 |
$c['name'] . '</b> <small>(ID: ' . $c['id'] . ', Photos: ' . $c['count'] . ')</small>'; |
| 578 |
echo '<form action="" method="post" style="display: inline;"> |
| 579 |
<input type="hidden" name="page" value="' . $page . '"> |
| 580 |
<input type="hidden" name="action" value="' . $mode . '">'; |
| 581 |
wp_nonce_field( 'wplr_debug_action' ); |
| 582 |
echo '<small class="wplr_delete" style="display: ' . ( $hasDeleted ? 'inline' : 'none' ) . ';"> |
| 583 |
<button type="submit" name="delete_keyword" value="' . $c['id'] . '" class="btn-link">' . |
| 584 |
__( 'Delete', 'wplr-sync' ) . '</button> |
| 585 |
</small></form>'; |
| 586 |
echo '</div>'; |
| 587 |
} |
| 588 |
else { |
| 589 |
$type = $c['type'] == 'folder' ? '<span class="dashicons dashicons-category"></span>' : '<span class="dashicons dashicons-format-gallery"></span>'; |
| 590 |
echo '<div class="wplr-elem wplr-' . $c['type'] |
| 591 |
. '" wplr-elem-type="' . $c['type'] . '" wplr-elem-id="' . $c['id'] . '" wplr-elem-name="' . $c['name'] . '">' |
| 592 |
. $type . ' ' . $c['name'] . ' <small>(ID: ' . $c['id'] . ')</small>'; |
| 593 |
|
| 594 |
echo '<form action="" method="post" style="display: inline;"> |
| 595 |
<input type="hidden" name="page" value="' . $page. '">'; |
| 596 |
wp_nonce_field( 'wplr_debug_action' ); |
| 597 |
echo '<small class="wplr_delete" style="display: none;"> |
| 598 |
<button type="submit" name="delete_collection" value="' . $c['id'] . '" class="btn-link">' . |
| 599 |
__( 'Delete', 'wplr-sync' ) . '</button> |
| 600 |
</small></form>'; |
| 601 |
echo '</div>'; |
| 602 |
} |
| 603 |
|
| 604 |
if ( ( $mode == 'hierarchy' && $c['type'] == 'folder' ) || |
| 605 |
( $mode == 'keywords' && count( $c['children'] ) > 0 ) ) { |
| 606 |
display_internal_hierarchy( $c['children'], $level + 1, $mode, $hasDeleted ); |
| 607 |
} |
| 608 |
else { |
| 609 |
if ( $mode == 'hierarchy' ) { |
| 610 |
$photos = $wpdb->get_results( $wpdb->prepare( "SELECT * FROM $tbl_r WHERE wp_col_id = %d ORDER BY sort LIMIT 25", $c['id'] ), OBJECT ); |
| 611 |
if ( count( $photos ) > 0 ) { |
| 612 |
$count = $wpdb->get_var( $wpdb->prepare( "SELECT COUNT(*) FROM $tbl_r WHERE wp_col_id = %d", $c['id'] ) ); |
| 613 |
echo '<div style="margin-left: 0px; padding: 5px 0px; margin-top: 2px; margin-bottom: 5px; border-top: 1px solid lightgray;">'; |
| 614 |
echo '<div style="float: left; margin-right: 2px; width: 32px; height: 26px; background: #444444; text-align: center; padding-top: 6px; font-size: 10px; color: white;">' . $count . '</div>'; |
| 615 |
foreach ( $photos as $photo ) { |
| 616 |
$src = wp_get_attachment_image_src( $photo->wp_id, 'thumbnail' ); |
| 617 |
if(!$src ){ |
| 618 |
echo '<div><span class="dashicons dashicons-no" style="float: left; margin-right: 2px; margin-bottom: 2px; font-size: 32px; line-height: 32px; color: red;"></span></div>'; |
| 619 |
continue; |
| 620 |
} |
| 621 |
echo '<div><a href="media.php?attachment_id=' . $photo->wp_id . '&action=edit"><img style="float: left; margin-right: 2px; margin-bottom: 2px;" width="32" height="32" src="' . $src[0] . '"></a></div>'; |
| 622 |
} |
| 623 |
echo '<div style="clear: both;"></div></div>'; |
| 624 |
} |
| 625 |
} |
| 626 |
} |
| 627 |
} |
| 628 |
if ( $level > 0 ) |
| 629 |
echo '</div>'; |
| 630 |
echo '</div>'; |
| 631 |
} |
| 632 |
display_internal_hierarchy( $hierarchy, 0, $mode, $hasDeleted ); |
| 633 |
?> |
| 634 |
<script> |
| 635 |
function wplr_toggle_delete() { |
| 636 |
jQuery('.wplr_delete').toggle(); |
| 637 |
} |
| 638 |
jQuery('.wplr-elem').hover(function () { |
| 639 |
var id = jQuery(this).attr('wplr-elem-id'); |
| 640 |
var ids = []; |
| 641 |
var name = jQuery(this).attr('wplr-elem-name'); |
| 642 |
var type = jQuery(this).attr('wplr-elem-type'); |
| 643 |
var content = ""; |
| 644 |
|
| 645 |
if (type == 'folder') { |
| 646 |
jQuery(this).next('div').find('.wplr-collection').each(function(i, v) { |
| 647 |
ids.push(jQuery(v).attr('wplr-elem-id')); |
| 648 |
}); |
| 649 |
id = ids.join(','); |
| 650 |
} |
| 651 |
if (type == 'keyword') { |
| 652 |
ids.push(id); |
| 653 |
jQuery(this).next('div').find('.wplr-keyword').each(function(i, v) { |
| 654 |
ids.push(jQuery(v).attr('wplr-elem-id')); |
| 655 |
}); |
| 656 |
id = ids.join(','); |
| 657 |
} |
| 658 |
|
| 659 |
if (type == 'collection' || type == 'folder') { |
| 660 |
content += 'Here are my photos about <i>' + name + ':</i><br />'; |
| 661 |
content += '[gallery wplr-collection' + (ids.length > 1 ? 's' : '') + '="' + id + '"]'; |
| 662 |
} |
| 663 |
else if (type == 'keyword') { |
| 664 |
content += 'Here are my photos about <i>' + name + ':</i><br />'; |
| 665 |
content += '[gallery wplr-keyword' + (ids.length > 1 ? 's' : '') + '="' + id + '"]'; |
| 666 |
|
| 667 |
// content += '<i>Keywords are not supported yet, if you are interested in this feature please come on the forum of the Meow Gallery and ask for it :) Here: <a href="https://wordpress.org/support/plugin/meow-gallery">Meow Gallery Support Forum</a><i>'; |
| 668 |
} |
| 669 |
jQuery('#shortcode-preview-code').html(content); |
| 670 |
jQuery('#shortcode-preview-code').show(); |
| 671 |
console.log(jQuery(this)); |
| 672 |
}); |
| 673 |
</script> |
| 674 |
<p> |
| 675 |
<small><input type="checkbox" name="unlocked" <?= ( $hasDeleted ? 'checked' : '' ) ?> onclick="wplr_toggle_delete()"> |
| 676 |
<?php _e( 'Unlock <b>delete</b>', 'wplr-sync' ) ?> |
| 677 |
</small> |
| 678 |
</p> |
| 679 |
<?php |
| 680 |
} |
| 681 |
|
| 682 |
function admin_css() { |
| 683 |
?> |
| 684 |
<style> |
| 685 |
|
| 686 |
.left { |
| 687 |
width: 450px; |
| 688 |
} |
| 689 |
|
| 690 |
.right { |
| 691 |
position: absolute; |
| 692 |
left: 460px; |
| 693 |
right: 10px; |
| 694 |
} |
| 695 |
|
| 696 |
.left-75 { |
| 697 |
width: 60%; |
| 698 |
} |
| 699 |
|
| 700 |
.right-25 { |
| 701 |
position: absolute; |
| 702 |
width: 34%; |
| 703 |
right: 20px; |
| 704 |
} |
| 705 |
|
| 706 |
.wplr-collection, .wplr-folder, .wplr-keyword { |
| 707 |
cursor: pointer; |
| 708 |
} |
| 709 |
|
| 710 |
.shortcode-preview { |
| 711 |
margin-bottom: 20px; |
| 712 |
background: #0085ba; |
| 713 |
padding: 10px; |
| 714 |
font-size: 12px; |
| 715 |
word-break: break-all; |
| 716 |
color: white; |
| 717 |
margin-top: -10px; |
| 718 |
} |
| 719 |
|
| 720 |
h3 { |
| 721 |
margin-bottom: 5px; |
| 722 |
} |
| 723 |
|
| 724 |
p { |
| 725 |
margin-top: 0px; |
| 726 |
margin-bottom: 10px; |
| 727 |
} |
| 728 |
|
| 729 |
.wplrsync-form { |
| 730 |
border: 1px solid lightgrey; |
| 731 |
padding: 5px; |
| 732 |
background: white; |
| 733 |
border-radius: 5px; |
| 734 |
width: 420px; |
| 735 |
} |
| 736 |
|
| 737 |
th { |
| 738 |
text-align: left; |
| 739 |
} |
| 740 |
|
| 741 |
#wpfooter { |
| 742 |
display: none; |
| 743 |
} |
| 744 |
|
| 745 |
</style> |
| 746 |
<?php |
| 747 |
} |
| 748 |
|
| 749 |
function display_ads() { |
| 750 |
return !get_option( 'meowapps_hide_ads', false ); |
| 751 |
} |
| 752 |
|
| 753 |
function display_title( $title = "Meow Apps", |
| 754 |
$author = "By <a style='text-decoration: none;' href='https://meowapps.com' target='_blank'>Jordy Meow</a>" ) { |
| 755 |
if ( !empty( $this->prefix ) && $title !== "Meow Apps" ) |
| 756 |
$title = apply_filters( $this->prefix . '_plugin_title', $title ); |
| 757 |
if ( $this->display_ads() ) { |
| 758 |
} |
| 759 |
?> |
| 760 |
<h1 style="line-height: 16px;"> |
| 761 |
<img width="42" style="margin-right: 10px; float: left; position: relative; top: -5px;" |
| 762 |
src="<?php echo self::$logo ?>"><?php echo $title; ?><br /> |
| 763 |
<span style="font-size: 12px"><?php echo $author; ?></span> |
| 764 |
</h1> |
| 765 |
<div style="clear: both;"></div> |
| 766 |
<?php |
| 767 |
} |
| 768 |
|
| 769 |
function admin_debug() { |
| 770 |
if ( !current_user_can( 'manage_options' ) ) { |
| 771 |
wp_die( __( 'You do not have sufficient permissions to access this page.' ) ); |
| 772 |
} |
| 773 |
|
| 774 |
// HEADER |
| 775 |
$this->admin_css(); |
| 776 |
?> |
| 777 |
<div class="wrap" > |
| 778 |
|
| 779 |
<?php echo $this->display_title( __( 'Debugging', 'wplr-sync' ) . " | Photo Engine" ); ?> |
| 780 |
<p>Those tools should be used for debugging purposed. Be careful when you are using them, especially the colored buttons (usually blue).</p> |
| 781 |
<?php |
| 782 |
|
| 783 |
global $wpdb; |
| 784 |
$table_name = $wpdb->prefix . "lrsync"; |
| 785 |
|
| 786 |
if ( !isset( $_POST['action'] ) && isset( $_GET['action'] ) ) { |
| 787 |
$_POST['action'] = $_GET['action']; |
| 788 |
} |
| 789 |
|
| 790 |
if ( isset( $_POST['action'] ) ) { |
| 791 |
|
| 792 |
// CSRF Protection: Verify nonce for POST requests |
| 793 |
if ( !isset( $_POST['_wpnonce'] ) || !wp_verify_nonce( $_POST['_wpnonce'], 'wplr_debug_action' ) ) { |
| 794 |
wp_die( __( 'Security check failed. Please try again.', 'wplr-sync' ) ); |
| 795 |
} |
| 796 |
|
| 797 |
$action = $_POST['action']; |
| 798 |
if ( $action == "reset" ) { |
| 799 |
$this->wplr->reset_db(); |
| 800 |
echo "<div class='updated'><p>" . |
| 801 |
__( 'The database was reset.', 'wplr-sync' ) . |
| 802 |
"</p></div>"; |
| 803 |
} |
| 804 |
else if ( $action == "duplicates" ) { |
| 805 |
$duplicates = $this->wplr->list_duplicates(); |
| 806 |
} |
| 807 |
else if ( $action == "scan" ) { |
| 808 |
$unlinks = $this->wplr->list_unlinks(); |
| 809 |
} |
| 810 |
else if ( $action == "list" ) { |
| 811 |
$list = $this->wplr->list_sync_media(); |
| 812 |
} |
| 813 |
else if ( $action == "link" ) { |
| 814 |
if ( $this->wplr->link_media( $_POST['lr_id'], $_POST['wp_id'] ) ) { |
| 815 |
echo "<div class='updated'><p>" . |
| 816 |
__( 'Link successful.', 'wplr-sync' ) . |
| 817 |
"</p></div>"; |
| 818 |
} |
| 819 |
else { |
| 820 |
echo "<div class='error'><p>" . $this->wplr->get_error()->message . "</p></div>"; |
| 821 |
} |
| 822 |
} |
| 823 |
else if ( $action == "linkinfo_upload" ) { |
| 824 |
if ( isset( $_FILES['file'], $_FILES['file']['tmp_name'] ) && !empty( $_FILES['file']['tmp_name'] ) ) { |
| 825 |
$tmp_path = $_FILES['file']['tmp_name']; |
| 826 |
$linkinfo = $this->wplr->linkinfo_upload( $tmp_path, null ); |
| 827 |
} |
| 828 |
else { |
| 829 |
$linkinfo = $this->wplr->linkinfo_media( $_POST['wp_id'] ); |
| 830 |
} |
| 831 |
if ( $linkinfo ) |
| 832 |
echo "<div class='updated'><p>" . |
| 833 |
__( 'Link info retrieved.', 'wplr-sync' ) |
| 834 |
. "</p></div>"; |
| 835 |
else |
| 836 |
echo "<div class='error'><p>" . $this->wplr->get_error()->message . "</p></div>"; |
| 837 |
} |
| 838 |
else if ( $action == "sync" ) { |
| 839 |
$tmp_path = $_FILES['file']['tmp_name']; |
| 840 |
$lrinfo = new Meow_WPLR_Sync_LRInfo(); |
| 841 |
$lrinfo->lr_id = $_POST['lr_id'] == "" ? -1 : $_POST['lr_id']; |
| 842 |
$lrinfo->lr_file = $_FILES['file']['name']; |
| 843 |
$lrinfo->lr_title = isset( $_POST['title'] ) ? $_POST['title'] : ""; |
| 844 |
$lrinfo->lr_caption = $_POST['caption']; |
| 845 |
$lrinfo->lr_desc = isset( $_POST['desc'] ) ? $_POST['desc'] : ""; |
| 846 |
$lrinfo->lr_alt_text = isset( $_POST['altText'] ) ? $_POST['altText'] : ""; |
| 847 |
$lrinfo->sync_title = isset( $_POST['syncTitle'] ) && $_POST['syncTitle'] == 'on'; |
| 848 |
$lrinfo->sync_caption = isset( $_POST['syncCaption'] ) && $_POST['syncCaption'] == 'on'; |
| 849 |
$lrinfo->sync_desc = isset( $_POST['syncDesc'] ) && $_POST['syncDesc'] == 'on'; |
| 850 |
$lrinfo->sync_alt_text = isset( $_POST['syncAltText'] ) && $_POST['syncAltText'] == 'on'; |
| 851 |
$lrinfo->type = $_FILES['file']['type']; |
| 852 |
if ( $this->wplr->sync_media( $lrinfo, $tmp_path ) ) { |
| 853 |
echo "<div class='updated'><p>"; |
| 854 |
echo sprintf( __( 'Lr ID %d was synchronized with the attachment.', 'wplr-sync' ), $_POST['lr_id'] ); |
| 855 |
echo "</p></div>"; |
| 856 |
} |
| 857 |
else |
| 858 |
echo "<div class='error'><p>" . $this->wplr->get_error()->message . "</p></div>"; |
| 859 |
|
| 860 |
} |
| 861 |
else if ( $action == "unlink" ) { |
| 862 |
if ( $this->wplr->unlink_media( $_POST['lr_id'], $_POST['wp_id'] ) ) { |
| 863 |
echo "<div class='updated'><p>"; |
| 864 |
echo sprintf( __( 'Media ID %d was unlinked.', 'wplr-sync' ), $_POST['lr_id'] ); |
| 865 |
echo "</p></div>"; |
| 866 |
} |
| 867 |
else |
| 868 |
echo "<div class='error'><p>" . $this->wplr->get_error()->message . "</p></div>"; |
| 869 |
} |
| 870 |
else if ( $action == "remove" ) { |
| 871 |
if ( $this->wplr->delete_media( $_POST['lr_id'] ) ) { |
| 872 |
echo "<div class='updated'><p>"; |
| 873 |
echo sprintf( __( 'Media ID %d was removed.', 'wplr-sync' ), $_POST['lr_id'] ); |
| 874 |
echo "</p></div>"; |
| 875 |
} |
| 876 |
else |
| 877 |
echo "<div class='error'><p>" . $this->wplr->get_error()->message . "</p></div>"; |
| 878 |
} |
| 879 |
else if ( $action != 'api' && $action != 'keywords' && $action != 'hierarchy' ) { |
| 880 |
echo "<div class='error'<p>Unknown action.</p></div>"; |
| 881 |
} |
| 882 |
|
| 883 |
} |
| 884 |
|
| 885 |
// CONTENT & FORMS |
| 886 |
?> |
| 887 |
<div class="right"> |
| 888 |
|
| 889 |
<h3><?php _e( 'Display', 'wplr-sync' ); ?></h3> |
| 890 |
<p class="buttons"> |
| 891 |
<form style="float: left; margin-right: 5px;" method="post" action=""> |
| 892 |
<input type="hidden" name="action" value="hierarchy"> |
| 893 |
<?php wp_nonce_field( 'wplr_debug_action' ); ?> |
| 894 |
<input type="submit" name="submit" id="submit" class="button" value="Show Hierarchy"> |
| 895 |
</form> |
| 896 |
<form style="float: left; margin-right: 5px;" method="post" action=""> |
| 897 |
<input type="hidden" name="action" value="keywords"> |
| 898 |
<?php wp_nonce_field( 'wplr_debug_action' ); ?> |
| 899 |
<input type="submit" name="submit" id="submit" class="button" value="Show Keywords"> |
| 900 |
</form> |
| 901 |
<form style="float: left; margin-right: 5px;" method="post" action=""> |
| 902 |
<input type="hidden" name="action" value="list"> |
| 903 |
<?php wp_nonce_field( 'wplr_debug_action' ); ?> |
| 904 |
<input type="submit" name="submit" id="submit" class="button" value="List Linked"> |
| 905 |
</form> |
| 906 |
<form style="float: left; margin-right: 5px;" method="post" action=""> |
| 907 |
<input type="hidden" name="action" value="scan"> |
| 908 |
<?php wp_nonce_field( 'wplr_debug_action' ); ?> |
| 909 |
<input type="submit" name="submit" id="submit" class="button" value="List Unlinked"> |
| 910 |
</form> |
| 911 |
<form style="float: left; margin-right: 5px;" method="post" action=""> |
| 912 |
<input type="hidden" name="action" value="duplicates"> |
| 913 |
<?php wp_nonce_field( 'wplr_debug_action' ); ?> |
| 914 |
<input type="submit" name="submit" id="submit" class="button" value="List Duplicates"> |
| 915 |
</form> |
| 916 |
<!-- <form style="float: left; margin-right: 5px;" method="post" action=""> |
| 917 |
<input type="hidden" name="action" value="api"> |
| 918 |
<input type="submit" name="submit" id="submit" class="button" value="API Ping"> |
| 919 |
</form> --> |
| 920 |
</p> |
| 921 |
<br /> |
| 922 |
|
| 923 |
<?php |
| 924 |
if ( isset( $_POST['action'] ) && $action == "scan" ) { |
| 925 |
echo '<br /><h3>' . __( 'Unlinked Media', 'wplr-sync' ) . '</h3>'; |
| 926 |
echo '<pre>'; |
| 927 |
print_r( $unlinks ); |
| 928 |
echo '</pre>'; |
| 929 |
} |
| 930 |
else if ( isset( $_POST['action'] ) && $action == "list" ) { |
| 931 |
echo '<br /><h3>' . __( 'Linked Media', 'wplr-sync' ) . '</h3>'; |
| 932 |
echo '<pre>'; |
| 933 |
print_r( $list ); |
| 934 |
echo '</pre>'; |
| 935 |
} |
| 936 |
else if ( isset( $_POST['action'] ) && $action == "linkinfo_upload" ) { |
| 937 |
echo '<pre>'; |
| 938 |
print_r( $linkinfo ); |
| 939 |
echo '</pre>'; |
| 940 |
} |
| 941 |
else if ( isset( $_POST['action'] ) && $action == "duplicates" ) { |
| 942 |
echo '<br /><h3>' . __( 'Duplicates', 'wplr-sync' ) . '</h3>'; |
| 943 |
echo '<pre>'; |
| 944 |
print_r( $duplicates ); |
| 945 |
echo '</pre>'; |
| 946 |
} |
| 947 |
else if ( isset( $_POST['action'] ) && $action == "api" ) { |
| 948 |
$boundary = wp_generate_password(24); |
| 949 |
$response = wp_remote_post( admin_url( 'admin-ajax.php' ), |
| 950 |
array( |
| 951 |
'headers' => array( 'content-type' => 'multipart/form-data; boundary=' . $boundary ), |
| 952 |
'body' => array( 'action' => 'lrsync_api', 'isAjax' => 1, 'data' => '' ) |
| 953 |
) |
| 954 |
); |
| 955 |
echo '<br /><h3>' . __( 'API Response', 'wplr-sync' ) . '</h3>'; |
| 956 |
echo '<pre>'; |
| 957 |
print_r( $response ); |
| 958 |
echo '</pre>'; |
| 959 |
} |
| 960 |
else { |
| 961 |
$this->display_hierarchy( isset( $_POST['action'] ) ? $action : null ); |
| 962 |
} |
| 963 |
?> |
| 964 |
</div> |
| 965 |
|
| 966 |
<div class="left"> |
| 967 |
<h3><?php _e( 'Link Info', 'wplr-sync' ) ?></h3> |
| 968 |
<p><?php _e( 'Link info for either a WP ID <b>or</b> the Uploaded File.', 'wplr-sync' ) ?></p> |
| 969 |
<form class="wplrsync-form" method="post" action="" enctype="multipart/form-data"> |
| 970 |
<input type="hidden" name="action" value="linkinfo_upload"> |
| 971 |
<?php wp_nonce_field( 'wplr_debug_action' ); ?> |
| 972 |
<table> |
| 973 |
<tr> |
| 974 |
<th scope="row"><label for="wp_id">WP ID</label></th> |
| 975 |
<td><input name="wp_id" type="text" id="wp_id" value="" class="regular-text code"></td> |
| 976 |
</tr> |
| 977 |
<tr> |
| 978 |
<th scope="row"><label for="file">File</label></th> |
| 979 |
<td><input name="file" type="file" id="file"></td> |
| 980 |
</tr> |
| 981 |
<tr> |
| 982 |
<th scope="row"></th> |
| 983 |
<td><input type="submit" name="submit" id="submit" class="button" value="Check"></td> |
| 984 |
</tr> |
| 985 |
</table> |
| 986 |
</form> |
| 987 |
|
| 988 |
<h3><?php _e( 'Link', 'wplr-sync' ) ?></h3> |
| 989 |
<p><?php _e( 'Will link the WP Media ID to the Lr ID.', 'wplr-sync' ) ?></p> |
| 990 |
<form class="wplrsync-form" method="post" action="" enctype="multipart/form-data"> |
| 991 |
<input type="hidden" name="action" value="link"> |
| 992 |
<?php wp_nonce_field( 'wplr_debug_action' ); ?> |
| 993 |
<table> |
| 994 |
<tr> |
| 995 |
<th scope="row"><label for="lr_id">Lr ID</label></th> |
| 996 |
<td><input name="lr_id" type="text" id="lr_id" value="" class="regular-text code"></td> |
| 997 |
</tr> |
| 998 |
<tr> |
| 999 |
<th scope="row"><label for="wp_id">Media ID</label></th> |
| 1000 |
<td><input name="wp_id" type="text" id="wp_id" value="" class="regular-text code"></td> |
| 1001 |
</tr> |
| 1002 |
<tr> |
| 1003 |
<th scope="row"></th> |
| 1004 |
<td><input type="submit" name="submit" id="submit" class="button button-primary" value="Link Media ID + Lr ID"></td> |
| 1005 |
</tr> |
| 1006 |
</table> |
| 1007 |
|
| 1008 |
</form> |
| 1009 |
|
| 1010 |
<h3><?php _e( 'Unlink', 'wplr-sync' ) ?></h3> |
| 1011 |
<p><?php _e( 'Will unlink the media.', 'wplr-sync' ) ?></p> |
| 1012 |
<form class="wplrsync-form" method="post" action=""> |
| 1013 |
<input type="hidden" name="action" value="unlink"> |
| 1014 |
<?php wp_nonce_field( 'wplr_debug_action' ); ?> |
| 1015 |
<table> |
| 1016 |
<tr> |
| 1017 |
<th scope="row"><label for="lr_id">Lr ID</label></th> |
| 1018 |
<td><input name="lr_id" type="text" id="lr_id" value="" class="regular-text code"></td> |
| 1019 |
</tr> |
| 1020 |
<tr> |
| 1021 |
<th scope="row"><label for="wp_id">Media ID</label></th> |
| 1022 |
<td><input name="wp_id" type="text" id="wp_id" value="" class="regular-text code"></td> |
| 1023 |
</tr> |
| 1024 |
<tr> |
| 1025 |
<th scope="row"></th> |
| 1026 |
<td><input type="submit" name="submit" id="submit" class="button button-primary" value="Unlink"></td> |
| 1027 |
</tr> |
| 1028 |
</table> |
| 1029 |
</form> |
| 1030 |
|
| 1031 |
<h3><?php _e( 'Sync', 'wplr-sync' ) ?></h3> |
| 1032 |
<p><?php _e( 'Will create the entry if doesn\'t exist, will update it if exists.', 'wplr-sync' ) ?></p> |
| 1033 |
<form class="wplrsync-form" method="post" action="" enctype="multipart/form-data"> |
| 1034 |
<input type="hidden" name="action" value="sync"> |
| 1035 |
<?php wp_nonce_field( 'wplr_debug_action' ); ?> |
| 1036 |
<table> |
| 1037 |
<tr> |
| 1038 |
<th scope="row"><label for="lr_id">Lr ID</label></th> |
| 1039 |
<td><input name="lr_id" type="text" id="lr_id" value="" class="regular-text code"></td> |
| 1040 |
</tr> |
| 1041 |
<tr> |
| 1042 |
<th scope="row"><label for="title">Title</label></th> |
| 1043 |
<td><input name="title" type="text" id="title" class="regular-text code"></td> |
| 1044 |
</tr> |
| 1045 |
<tr> |
| 1046 |
<th scope="row"><label for="title">Caption</label></th> |
| 1047 |
<td><input name="caption" type="text" id="caption" class="regular-text code"></td> |
| 1048 |
</tr> |
| 1049 |
<tr> |
| 1050 |
<th scope="row"><label for="title">Desc</label></th> |
| 1051 |
<td><input name="desc" type="text" id="desc" class="regular-text code"></td> |
| 1052 |
</tr> |
| 1053 |
<tr> |
| 1054 |
<th scope="row"><label for="title">Alt</label></th> |
| 1055 |
<td><input name="altText" type="text" id="altText" class="regular-text code"></td> |
| 1056 |
</tr> |
| 1057 |
<tr> |
| 1058 |
<th scope="row"><label for="file">File</label></th> |
| 1059 |
<td><input name="file" type="file" id="file"></td> |
| 1060 |
</tr> |
| 1061 |
<tr> |
| 1062 |
<th scope="row"><label for="sync">Sync</label></th> |
| 1063 |
<td> |
| 1064 |
<label><input type="checkbox" id="syncTitle" name="syncTitle">Title</label> |
| 1065 |
<label><input type="checkbox" id="syncCaption" name="syncCaption">Caption</label> |
| 1066 |
<label><input type="checkbox" id="syncDesc" name="syncDesc">Desc</label> |
| 1067 |
<label><input type="checkbox" id="syncAltText" name="syncAltText">Alt</label> |
| 1068 |
</td> |
| 1069 |
</tr> |
| 1070 |
<tr> |
| 1071 |
<th scope="row"></th> |
| 1072 |
<td><input type="submit" name="submit" id="submit" class="button button-primary" value="Sync Media"></td> |
| 1073 |
</tr> |
| 1074 |
</table> |
| 1075 |
</form> |
| 1076 |
|
| 1077 |
<h3><?php _e( 'Remove', 'wplr-sync' ) ?></h3> |
| 1078 |
<p><?php _e( 'Will remove the media.', 'wplr-sync' ) ?></p> |
| 1079 |
<form class="wplrsync-form" method="post" action=""> |
| 1080 |
<input type="hidden" name="action" value="remove"> |
| 1081 |
<?php wp_nonce_field( 'wplr_debug_action' ); ?> |
| 1082 |
<table> |
| 1083 |
<tr> |
| 1084 |
<th scope="row"><label for="lr_id">Lr ID</label></th> |
| 1085 |
<td><input name="lr_id" type="text" id="lr_id" value="" class="regular-text code"></td> |
| 1086 |
</tr> |
| 1087 |
<tr> |
| 1088 |
<th scope="row"></th> |
| 1089 |
<td><input type="submit" name="submit" id="submit" class="button button-primary" value="Remove Media"></td> |
| 1090 |
</tr> |
| 1091 |
</table> |
| 1092 |
</form> |
| 1093 |
|
| 1094 |
<h3><?php _e( 'Actions', 'wplr-sync' ) ?></h3> |
| 1095 |
<p class="buttons"> |
| 1096 |
<?php _e( 'Be careful. Those buttons are dangerous.', 'wplr-sync' ) ?> |
| 1097 |
<form style="margin-right: 5px;" method="post" action=""> |
| 1098 |
<input type="hidden" name="action" value="reset"> |
| 1099 |
<?php wp_nonce_field( 'wplr_debug_action' ); ?> |
| 1100 |
<input type="submit" name="submit" id="submit" class="button button-primary" |
| 1101 |
value="<?php _e( 'Reset Photo Engine DB', 'wplr-sync' ) ?>"> |
| 1102 |
</form> |
| 1103 |
</p> |
| 1104 |
|
| 1105 |
</div> |
| 1106 |
</div> |
| 1107 |
</div> |
| 1108 |
<?php |
| 1109 |
} |
| 1110 |
|
| 1111 |
// Add metabox for format warning on media edit page |
| 1112 |
function add_format_warning_metabox() { |
| 1113 |
global $post; |
| 1114 |
if ( $post && $post->post_type === 'attachment' ) { |
| 1115 |
// Check if this media has a format mismatch |
| 1116 |
global $wplr; |
| 1117 |
$mismatch_info = $wplr->check_format_mismatch( $post->ID ); |
| 1118 |
if ( $mismatch_info && $mismatch_info['has_mismatch'] ) { |
| 1119 |
add_meta_box( |
| 1120 |
'wplr_format_warning', |
| 1121 |
__( 'Format Notice', 'wplr-sync' ), |
| 1122 |
array( $this, 'format_warning_metabox_content' ), |
| 1123 |
'attachment', |
| 1124 |
'side', |
| 1125 |
'default' |
| 1126 |
); |
| 1127 |
} |
| 1128 |
} |
| 1129 |
} |
| 1130 |
|
| 1131 |
// Display format warning content |
| 1132 |
function format_warning_metabox_content( $post ) { |
| 1133 |
global $wplr; |
| 1134 |
$mismatch_info = $wplr->check_format_mismatch( $post->ID ); |
| 1135 |
if ( $mismatch_info && $mismatch_info['has_mismatch'] ) { |
| 1136 |
?> |
| 1137 |
<div style="padding: 10px; background: #fff3cd; border: 1px solid #ffeeba; border-radius: 4px;"> |
| 1138 |
<p style="margin: 0 0 10px 0;"> |
| 1139 |
<strong>⚠️ <?php _e( 'Format Mismatch Detected', 'wplr-sync' ); ?></strong> |
| 1140 |
</p> |
| 1141 |
<p style="margin: 0 0 10px 0; font-size: 13px;"> |
| 1142 |
<?php |
| 1143 |
printf( |
| 1144 |
__( 'This file has a .%s extension but contains %s data.', 'wplr-sync' ), |
| 1145 |
esc_html( $mismatch_info['file_extension'] ), |
| 1146 |
esc_html( strtoupper( $mismatch_info['actual_format'] ) ) |
| 1147 |
); |
| 1148 |
?> |
| 1149 |
</p> |
| 1150 |
<p style="margin: 0 0 8px 0; font-size: 12px; color: #666;"> |
| 1151 |
<?php _e( 'This happens when you change export formats in Lightroom after photos have already been published. Due to Lightroom SDK limitations, there is no perfect solution to preserve the original format during re-exports.', 'wplr-sync' ); ?> |
| 1152 |
</p> |
| 1153 |
<p style="margin: 0; font-size: 12px; color: #666;"> |
| 1154 |
<strong><?php _e( 'Good news:', 'wplr-sync' ); ?></strong> <?php _e( 'Browsers detect the actual format from the file content, not the extension, so your images will display correctly.', 'wplr-sync' ); ?> |
| 1155 |
</p> |
| 1156 |
<p style="margin: 8px 0 0 0; font-size: 12px; color: #666;"> |
| 1157 |
<?php |
| 1158 |
printf( |
| 1159 |
__( 'If you want to fix the file extensions, you can use the <a href="%s" target="_blank">Media File Renamer</a> plugin.', 'wplr-sync' ), |
| 1160 |
'https://wordpress.org/support/plugin/media-file-renamer/' |
| 1161 |
); |
| 1162 |
?> |
| 1163 |
</p> |
| 1164 |
</div> |
| 1165 |
<?php |
| 1166 |
} |
| 1167 |
} |
| 1168 |
} |
| 1169 |
|
| 1170 |
?> |
| 1171 |
|