Skip to content
New issue

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

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

Already on GitHub? Sign in to your account

Issue 313: Create new connector for Theme Editor #341

Merged
merged 48 commits into from
Apr 1, 2014
Merged
Show file tree
Hide file tree
Changes from 24 commits
Commits
Show all changes
48 commits
Select commit Hold shift + click to select a range
5b99934
[issue-313] Add Editor connector
Mar 13, 2014
5eface0
[issue-313] Clone textarea
Mar 13, 2014
c600a44
[issue-313] Log file changes
Mar 13, 2014
c24db6b
[issue-313] Improve log message
Mar 13, 2014
2a288a3
[issue-313] Use theme name
Mar 13, 2014
2a36225
[issue-313] Make sure `get_current_screen` function exists
Mar 14, 2014
e4cfa48
[issue-313] Save file data in static var on admin_init hook
Mar 14, 2014
6970bd9
[issue-313] Add method to check if edition is requested
Mar 14, 2014
359f734
[issue-313] Use new method in admin_init hook callback
Mar 14, 2014
a58d93c
[issue-313] Compare file contents
Mar 14, 2014
7a6b19c
[issue-313] Remove redundant method
Mar 14, 2014
ef8a389
[issue-313] Remove client-side solution
Mar 14, 2014
f3be1cd
[issue-313] Ignore theme editor changes in Installer connector
Mar 14, 2014
22ff0f8
[issue-313] Add action link to Edit File
Mar 14, 2014
20376f5
Add Edit Theme action link
Mar 14, 2014
b157e3a
[issue-313] Simplify log message
Mar 14, 2014
dca4a93
[issue-313] Update connector name to Theme Editor
Mar 14, 2014
7d9b8fd
[issue-313] Use theme name as Context
Mar 14, 2014
d133392
[issue-313] Change action to Updated
Mar 14, 2014
cd4014a
[issue-313] Hide action links for users without permissions
Mar 14, 2014
c372356
[issue-313] Tiny log message improvement
Mar 14, 2014
6e6534d
[issue-313] Document and simplify method
Mar 14, 2014
25b0eea
[issue-313] Ignore file contents in logs
Mar 14, 2014
5169f80
[issue-313] Syntax tidying
Mar 14, 2014
e337678
[issue-313] Use wp_stream_filter_input()
Mar 14, 2014
a5274c6
Merge branch 'develop' into issue-313
Mar 18, 2014
3b0b750
Use wp_stream_filter_input where possible
frankiejarrett Mar 24, 2014
d21362f
[issue-313] Get message in method
Mar 26, 2014
a8e1d1c
[issue-313] Update summary
Mar 26, 2014
8233914
[issue-313] Update stream context table
Mar 26, 2014
31e38fa
Add action to WHERE
Mar 26, 2014
ba590f9
[issue-313] Find theme object by name
Mar 26, 2014
5a02d2f
[issue-313] Update meta
Mar 26, 2014
ce2ad98
[issue-313] Move update routine to Editor connector class
Mar 26, 2014
55e233c
[issue-313] Use new method
Mar 26, 2014
f61b559
[issue-313] Get global $wpdb
Mar 26, 2014
33d640f
[issue-313] Don't display action links with insufficient meta
Mar 26, 2014
b4df52a
[issue-313] Use theme slug in `theme` meta
Mar 26, 2014
93b34c1
[issue-313] Syntax tweaks
Mar 26, 2014
cab8091
[issue-313] Replace `theme` meta key with `theme_slug`
Mar 26, 2014
e677fcc
[issue-313] Beautify sprintf
Mar 26, 2014
bc11f7e
Bumping version for upgrade routine
frankiejarrett Mar 27, 2014
4ccc84c
Merge branch 'develop' into issue-313
frankiejarrett Mar 27, 2014
922c17a
[issue-313] Move update routine to installer
Mar 28, 2014
6562d1b
Run migrate routine after connectors are registered
frankiejarrett Mar 29, 2014
fe62bae
[issue-313] Add action, not filter
Apr 1, 2014
26967b5
Summary tweak for theme editor updates
frankiejarrett Apr 1, 2014
989b1f0
Code format tweaks
frankiejarrett Apr 1, 2014
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
182 changes: 182 additions & 0 deletions connectors/editor.php
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'] ) {
Copy link
Contributor

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:

'update' !== wp_stream_filter_input( INPUT_POST, 'action' )

And elsewhere throughout this method...

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;
}

}
2 changes: 1 addition & 1 deletion connectors/installer.php
Original file line number Diff line number Diff line change
Expand Up @@ -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 ) ) {
Copy link
Contributor

Choose a reason for hiding this comment

The 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.

Copy link
Author

Choose a reason for hiding this comment

The 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.

Copy link
Contributor

Choose a reason for hiding this comment

The 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.

Copy link
Author

Choose a reason for hiding this comment

The 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:

  1. It updates summary, connector, context and action for all previous file editions
  2. It tries to find a theme by name and if one is found, theme slug is saved in meta
  3. If we have theme slug in meta, we are able to display action links: Edit File and Edit Theme. Otherwise they are not present.

What I need to confirm is that connectors classes are available when WP_Stream_Install::update() is called (https://github.com/x-team/wp-stream/blob/issue-313/includes/install.php#L207-L211), because I tested it by calling Editor's updater directly.

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@powelski This is why we introduced the wp_stream_after_connectors_registration filter and place all migration methods directly inside the WP_Stream_Install class.

See: https://github.com/x-team/wp-stream/blob/28e583ae303576849e3ff7d844a73488a256610e/includes/install.php#L201-L238

We should use this same approach and keep all migration logic in the same place.

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@powelski bump 😺

Copy link
Author

Choose a reason for hiding this comment

The 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?

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@powelski To the WP_Stream_Install class, yes. And we can run it after all connectors have registered.

return $location;
}

Expand Down