-
Notifications
You must be signed in to change notification settings - Fork 2.7k
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
Fix naive filtering of uploads directory. #6211
Fix naive filtering of uploads directory. #6211
Conversation
Test using WordPress PlaygroundThe changes in this pull request can previewed and tested using a WordPress Playground instance. WordPress Playground is an experimental project that creates a full WordPress instance entirely within the browser. Some things to be aware of
For more details about these limitations and more, check out the Limitations page in the WordPress Playground documentation. |
97744d7
to
da4c272
Compare
The following accounts have interacted with this PR and/or linked issues. I will continue to update these lists as activity occurs. You can also manually ask me to refresh this list by adding the Core Committers: Use this line as a base for the props when committing in SVN:
To understand the WordPress project's expectations around crediting contributors, please review the Contributor Attribution page in the Core Handbook. |
@matiasbenedetto Ping. Unable to do so by adding you as a reviewer, sorry. I really need to fix that. |
What I did not like about this prior So if we want to keep the filter like this, we should really rename it to something like |
I agree. I had something to convert |
13af958
to
c1edfba
Compare
@swissspidy The function is called directly and used as a getter during the deletion of posts. I'll look at splitting it out so that WordPress runs a filter on wordpress-develop/src/wp-includes/fonts.php Line 191 in b64bfae
|
I'm not entirely sure that this is needed when this PR was merged in Gutenberg. @peterwilsoncc Can you explain why this is needed aswell? |
@costdev I think the rationale is here: WordPress/gutenberg#58696 (comment) |
This is testing fine on my end. I tried these cases:
add_filter( 'upload_dir', function ( $ul ) {
remove_filter( 'upload_dir', 'wp_get_font_dir' );
return $ul;
}, 5 );
/**
* Define a custom font directory for the WP Font Library.
*/
function alter_wp_fonts_dir( $defaults ) {
$wp_upload_dir = wp_get_upload_dir();
$uploads_basedir = $wp_upload_dir['basedir'];
$uploads_baseurl = $wp_upload_dir['baseurl'];
$fonts_dir = $uploads_basedir . '/fonts';
// Generate the URL for the fonts directory from the font dir.
$fonts_url = str_replace( $uploads_basedir, $uploads_baseurl, $fonts_dir );
$defaults['path'] = $fonts_dir;
$defaults['url'] = $fonts_url;
return $defaults;
}
add_filter( 'font_dir', 'alter_wp_fonts_dir' ); In the 3 cases, the fonts were successfully written in the expected folder:
Apart from that, I agree about that receiving a parameter in |
I've pushed 19cc1c7 which is nothing more than a thought bubble at this stage.
add_filter( 'upload_dir', function ( $ul ) {
remove_filter( 'upload_dir', 'wp_get_font_dir' );
return $ul;
}, 5 ); I don't really like the need for extending the number of functions but figured I'd push up the thought bubble so I can get feedback on it and figure out how to take a cleaner approach that allows for consistency using the new functions as a getter. |
@azaozz There is no way to pass a custom directory as an override. The upload handlers simply call wordpress-develop/src/wp-admin/includes/file.php Lines 975 to 982 in 14d55b8
A use case for an extender may be to make use of the feature outside of the site-editor. For example via the customizer for a classic theme or elsewhere for a hybrid theme. I'm not sure what else extenders will come up with but I'm often impressed by their ingenuity when extending WP. My main concern with the lambda filter is that it works around the bug rather than fixes the bug. I've worked a lot on the feature over the last few weeks and don't trust myself to remember that I need a work-around if adding code elsewhere, let alone another contributor who has been less involved. At a defensive coding level, if it's just as simple to fix a bug as to work around it then Core should always go with the former. |
Right. So the "override" could probably be something as simple as: if ( isset( $overrides['font_upload'] ) ) {
$uploads = wp_get_font_dir( 'create' ); // Passing "create" to indicate to make the dir if needed
} else {
$uploads = wp_upload_dir( $time );
}
/*
* A writable uploads dir will pass this test. Again, there's no point
* overriding this one.
*/
if ( ! ( $uploads && false === $uploads['error'] ) ) {
return call_user_func_array( $upload_error_handler, array( &$file, $uploads['error'] ) );
} Internally wp_get_font_dir() uses wp_upload_dir() if /fonts has to be moved there. Both of these functions have filters, etc. so extenders will have no problems hooking/tweaking anything they need? (I know, the "design" with overrides here is super old and non-intuitive (imho). It's been there since WP 1.5 I think.) |
I think we'd need to reproduce Mainly, though, it's as you say: it's extending an unintuitive API. It's also pretty easy to accidentally remove some of the security built in to the handlers using it so encouraging it's use further doesn't seem like a good idea. e3a5206 is an example of where it can lead to problems. |
I've been working through this PR over the last couple of days, and here are my notes: Given the constraints of
I can't find a better way of handling this than what we have in this PR. That said, stepping back, the implementation does still seem a bit odd to me, and I wonder if that's a hint there's a better way. For example, the default font path is created That leads me to wondering, what other filters are out there in the wild for Also, if the most common use case for changing the fonts directory is moving it to a different, singular location (e.g. |
That's fair. I can rip that out if you wish and merge it in to a renamed A part of my thinking was that it would make it easier for extenders and hosts to switch to |
I did a search of the plugin repo for I'm still not keen on adding another override to handling uploads. Even accepting that I don't want to introduce a specific |
I've been looking at this PR a bit and I'm not entirely sure I follow everything just yet.
Personally, I agree with @azaozz I don't know why anyone would do this and if I'm reading properly, it's because there's no way to indicate the target directory properly in the wp upload function. So,I think I'd favor improving the upload primitive instead. But improving the upload primitive, whether that means a newer function or modifications to the existing function or something else feels like a bigger undertaking at this point. So I'm actually fine with this PR. |
That's also my key takeaway here. Given that there will be likely more folders like this in the future, we should definitely overhaul this whole thing in the future. That also means any modifications now should keep that in mind. So the approach here to fix the infinite loop seems fine to me as a start. Just a couple of suggestions/thoughts on the code itself:
|
Yep, I agree. The current code implements the needed functionality despite the constrains. My guess is that these constrains are left over from when that functionality was implemented in a plugin. (There is a better way to do that btw. Instead of trying to solve similar cases by imposing constrains, some temporary code can be introduced while WP is in development, and removed before release. All "feature plugins" can request such temp code, filters, settings, constants, etc.) The question is: why not modify wp_handle_upload() in a simple, easy to follow, backwards compatible way? Imho the current patch here has higher chances to introduce errors/edge cases, and, as it uses nested filters, possible interference from existing code. The fact is that wp_handle_upload() is a function that is re-used for new functionality. It is a standard practice to extend the functionality of the existing code to accommodate the new requirements. Yes, it is usually possible to use filters to accomplish the same tasks. However this doesn't make sense unless the filters are designed to also be used by plugin and theme authors. I.e. the filters that are used to extend the existing WP code and implement the new functionality would need to "make sense" and be useful for plugins. I somehow don't think this is the case here. |
Hmm, I tend to disagree. Adding support for another (simple) parameter to a function seems quite "safer" as there is no chance to break backwards compatibility or to introduce edge cases to existing code. On the other hand using nested filters is a lot more complex, has some chance to introduce both back-compat problems and edge cases with existing plugins or themes.
Thinking that if this patch is to be added to WP 6.5 few days before release at least the new functions have to be private, hidden, and not accessible by plugins in any way. That would allow this code to be improved and these functions to be removed much easier, instead of having to support them "forever".
Big +1! To account for this thinking that this code needs to be "fixed" and any helper functions made private and added to a locked-down class, etc. |
The new functions need to be accessible to WordPress so are required to be public.
I'm not sure what extenders will do either. A part of my concern is for future WordPress contributors unaware of the history. As the FL gets extended we need to avoid the infinite loop trap as a defensive coding technique.
This mirrors the uploads API, |
…ncc/wordpress-develop into fix/font-filter-infinite-loop
This is a comment on a closed PR that was committed to WP 6.5 but for posterity's sake I think it would be good to make a tl;dr list of the points from the above reviews.
I'd also want to make is clear that I'm not trying to blame anybody whit this review. This PR was reviewed and committed during the "late" RC stage of WP 6.5, only few days before the (planned) release. Everybody was under a significant pressure at that time, and mistakes can happen at any point. The follow-up Trac ticket that fixes these issues is https://core.trac.wordpress.org/ticket/60835. |
@azaozz I'm not going to debate the merit of defensive coding so future maintainers of the code can perform upkeep without the risk of breaking a filter been used in the way it is intended to be used. It's just pointless. This PR was approved by a tech lead after multiple reviews in the two weeks leading up to its commit. |
@peterwilsoncc Thanks for you replay.
Sorry that I didn't make myself clear enough. I'm not discussing or debating anything here. The above comment is an attempt for a tl;dr of my review of this PR, nothing more.
Right. It was approved on the condition that this code will be fixed in WP 6.6. See #6211 (comment).
Sorry but not sure what you mean by that. Are you saying that it is okay for the newly introduced |
Prevent infinite loops getting the font directory.
Fast follow for r57740 / 9c415ed
This allows for WordPress extenders to filter the uploads directory to the font directory in the typical WordPress fashion, ie
add_filter( 'upload_dir', 'wp_get_font_dir' );
.On it's own this would work but can trigger infinite loops on hosts calling
wp_upload_dir()
orwp_get_upload_dir
on thefont_dir
filter.It looks like this will need to be committed to wordpress-develop prior to Gutenberg.
Fixes WordPress/gutenberg#58696
Fixes https://core.trac.wordpress.org/ticket/60652
This Pull Request is for code review only. Please keep all other discussion in the Trac ticket. Do not merge this Pull Request. See GitHub Pull Requests for Code Review in the Core Handbook for more details.