-
Notifications
You must be signed in to change notification settings - Fork 115
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
Issue 313: Create new connector for Theme Editor #341
Changes from 24 commits
5b99934
5eface0
c600a44
c24db6b
2a288a3
2a36225
e4cfa48
6970bd9
359f734
a58d93c
7a6b19c
ef8a389
f3be1cd
22ff0f8
20376f5
b157e3a
dca4a93
7d9b8fd
d133392
cd4014a
c372356
6e6534d
25b0eea
5169f80
e337678
a5274c6
3b0b750
d21362f
a8e1d1c
8233914
31e38fa
ba590f9
5a02d2f
ce2ad98
55e233c
f61b559
33d640f
b4df52a
93b34c1
cab8091
e677fcc
bc11f7e
4ccc84c
922c17a
6562d1b
fe62bae
26967b5
989b1f0
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,182 @@ | ||
<?php | ||
|
||
class WP_Stream_Connector_Editor extends WP_Stream_Connector { | ||
|
||
/** | ||
* Context name | ||
* | ||
* @var string | ||
*/ | ||
public static $name = 'editor'; | ||
|
||
/** | ||
* Actions registered for this context | ||
* | ||
* @var array | ||
*/ | ||
public static $actions = array(); | ||
|
||
/** | ||
* Actions registered for this context | ||
* | ||
* @var array | ||
*/ | ||
private static $edited_file = array(); | ||
|
||
/** | ||
* Register all context hooks | ||
* | ||
* @return void | ||
*/ | ||
public static function register() { | ||
parent::register(); | ||
add_action( 'load-theme-editor.php', array( __CLASS__, 'get_edition_data' ) ); | ||
add_filter( 'wp_redirect', array( __CLASS__, 'log_changes' ) ); | ||
} | ||
|
||
/** | ||
* Return translated context label | ||
* | ||
* @return string Translated context label | ||
*/ | ||
public static function get_label() { | ||
return __( 'Theme Editor', 'stream' ); | ||
} | ||
|
||
/** | ||
* Return translated action labels | ||
* | ||
* @return array Action label translations | ||
*/ | ||
public static function get_action_labels() { | ||
return array( | ||
'updated' => __( 'Updated', 'stream' ), | ||
); | ||
} | ||
|
||
/** | ||
* Return translated context labels | ||
* | ||
* @return array Context label translations | ||
*/ | ||
public static function get_context_labels() { | ||
$themes = wp_get_themes(); | ||
|
||
$themes_slugs = array_map( | ||
function( $theme ) { | ||
return $theme->get_template(); | ||
}, | ||
$themes | ||
); | ||
|
||
$themes_names = array_map( | ||
function( $theme ) { | ||
return (string) $theme; | ||
}, | ||
$themes | ||
); | ||
|
||
return array_combine( $themes_slugs, $themes_names ); | ||
} | ||
|
||
/** | ||
* Add action links to Stream drop row in admin list screen | ||
* | ||
* @filter wp_stream_action_links_{connector} | ||
* @param array $links Previous links registered | ||
* @param int $record Stream record | ||
* @return array Action links | ||
*/ | ||
public static function action_links( $links, $record ) { | ||
if ( current_user_can( 'edit_theme_options' ) ) { | ||
$file_name = get_stream_meta( $record->ID, 'file', true ); | ||
$theme_name = get_stream_meta( $record->ID, 'theme', true ); | ||
|
||
$links[ __( 'Edit File', 'stream' ) ] = admin_url( | ||
sprintf( | ||
'theme-editor.php?theme=%s&file=%s', | ||
$theme_name, | ||
$file_name | ||
) | ||
); | ||
|
||
$links[ __( 'Edit Theme', 'stream' ) ] = admin_url( | ||
sprintf( | ||
'themes.php?theme=%s', | ||
$theme_name | ||
) | ||
); | ||
} | ||
|
||
return $links; | ||
} | ||
|
||
/** | ||
* @action load-theme-editor.php | ||
*/ | ||
public static function get_edition_data() { | ||
if ( 'POST' !== $_SERVER['REQUEST_METHOD'] ) { | ||
return; | ||
} | ||
|
||
if ( ! isset( $_POST['action'] ) || 'update' !== $_POST['action'] ) { | ||
return; | ||
} | ||
|
||
$theme_name = ( isset( $_POST['theme'] ) && $_POST['theme'] ? $_POST['theme'] : get_stylesheet() ); | ||
$theme = wp_get_theme( $theme_name ); | ||
|
||
if ( ! $theme->exists() || ( $theme->errors() && 'theme_no_stylesheet' === $theme->errors()->get_error_code() ) ) { | ||
return; | ||
} | ||
|
||
$allowed_files = $theme->get_files( 'php', 1 ); | ||
$style_files = $theme->get_files( 'css' ); | ||
$allowed_files['style.css'] = $style_files['style.css']; | ||
|
||
if ( empty( $_POST['file'] ) ) { | ||
$file_name = 'style.css'; | ||
$file_path = $allowed_files['style.css']; | ||
} else { | ||
$file_name = $_POST['file']; | ||
$file_path = $theme->get_stylesheet_directory() . '/' . $file_name; | ||
} | ||
|
||
$file_contents_before = file_get_contents( $file_path ); | ||
|
||
self::$edited_file = compact( | ||
'file_name', | ||
'file_path', | ||
'file_contents_before', | ||
'theme' | ||
); | ||
} | ||
|
||
/** | ||
* @filter wp_redirect | ||
*/ | ||
public static function log_changes( $location ) { | ||
if ( ! empty( self::$edited_file ) ) { | ||
$file_contents_after = file_get_contents( self::$edited_file['file_path'] ); | ||
|
||
if ( $file_contents_after !== self::$edited_file['file_contents_before'] ) { | ||
$theme_slug = self::$edited_file['theme']->get_template(); | ||
$properties = array( | ||
'file' => self::$edited_file['file_name'], | ||
'theme_name' => (string) self::$edited_file['theme'], | ||
'theme' => $theme_slug, | ||
); | ||
|
||
self::log( | ||
__( '"%1$s" was updated in "%2$s"', 'stream' ), | ||
$properties, | ||
null, | ||
array( $theme_slug => 'updated' ) | ||
); | ||
} | ||
} | ||
|
||
return $location; | ||
} | ||
|
||
} |
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -312,7 +312,7 @@ public static function callback_pre_set_site_transient_update_plugins( $value ) | |
} | ||
|
||
public static function callback_wp_redirect( $location ) { | ||
if ( ! preg_match( '#(plugin|theme)-editor.php#', $location, $match ) ) { | ||
if ( ! preg_match( '#(plugin)-editor.php#', $location, $match ) ) { | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. @powelski Shouldn't we then also include an update routine to fix past entries? Otherwise we will not be maintaining proper backwards compatibility. The old entries should be changed to the new Theme Editor connector with the proper context being the theme name. There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. @fjarrett We can update summaries, but it's not possible to provide action links as I did here, because we don't have theme's slug in meta, only the name. Unless we do trick, like fetching available themes and adding theme slug meta for all matches. Not perfect, but worth consideration. There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. @powelski I'm more concerned about just updating the Summary, Connector and Context more than the action links. There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. @fjarrett Okay, I developed the updater. I tested it carefully. This how it works:
What I need to confirm is that connectors classes are available when There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. @powelski This is why we introduced the We should use this same approach and keep all migration logic in the same place. There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. @powelski bump 😺 There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. @fjarrett So you mean that this functionality should be moved from Editor's class to updater directly, is this correct? There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. @powelski To the |
||
return $location; | ||
} | ||
|
||
|
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
@powelski Nice opportunity to use
wp_stream_filter_input()
here:And elsewhere throughout this method...