wecodemore / wpstarter

Easily bootstrap whole site Composer packages for WordPress.
https://wecodemore.github.io/wpstarter/
MIT License
244 stars 34 forks source link

Allow installing plugin/themes inside WordPress wp-content folder #55

Closed gmazzap closed 8 years ago

gmazzap commented 8 years ago

In WP Starter docs and in pretty much all the documentation out there regarding usage of Composer + WordPress the wp-content folder is placed outside the WordPress root.

So the wp-content shipped with WordPress package is not used. WP Starter allows to:

There was discussion to also provide option to complete delete it (see #28).

So far, so good.


The problem is when someone want to use the wp-content folder shipped with WordPress as the actual wp-content folder, so install themes and plugins via Composer in it.

I don't really like this approach for different reason, to name one I dislike have packages inside other packages. However I found myself in the need to do it when migrating existing websites, that in great majority of the cases have wp-content inside WordPress folder.

There's a big issue with this, that is not really related to WP Starter, but in a broader way to Composer + WordPress.

Who develops plugin and themes for WP does not declare in them a dependency to WordPress package, for the reason that they can be installed with Composer in a website where Composer is not used to manage the entire website. In that case, declaring a dependency to WordPress package would mean to have a whole WordPress install inside plugin vendor folder...

Since plugins and themes does not declare dependency to WordPress, Composer has no clue that they depends on WordPress, and it is very possible that all or some plugin are installed before WordPress.

The issue here is that if the target installation folder for a package is already there when the package is going to be installed, Composer empties the package folder, than start package installation.

So if plugins/themes are setup to be installed in /wp-content subfolder of WordPress package, all the plugin/themes that are installed by Composer before WordPres are lost when WordPress package is installed.

If to install a package inside another is not a good idea, do that for packages that are not dependent, as much as Composer is concerned, is a very bad idea.


I already experimented different ways to solve this problem:

all of them worked, somehow, and I was able to solve the problem at end, but none of them was ideal, as the next time I have the same problem again I will need to either copy and paste what I have in another project.

I could create a Composer plugin that takes one of the approaches above and makes it generally usable, but I am not very keen to do that.

Another approach I have not tried yet, but I think could be the proper solution (if it will work :)) is to "live" inject WordPress dependency to themes / plugin packages.

That could be implemented as Composer plugin that:

  1. look at all the packages that Composer is going to install, to see if there's one or more packages of wordpress-core type. If no WP core packages foind, the plugin would do nothing, otherwise go to step 2.
  2. look at all the packages that Composer is going to install, to see if there's one or more packages of wordpress-plugin, wordpress-muplugin and wordpress-theme types. If yes, dependency to wordpress-core package(s) is injected "on the fly" to all of them. This way Composer will always install core package(s) before plugin and themes, solving the issue.

The plugin will hook pre install and pre update events to perform these tasks.

The main problem with this approach is that I have no idea if that is possible at all :D

I'll try to write this as soon as I find the time, but if someone want to do it before I do, that wold be great.

If this plugin comes to life and is proven to work, maybe there could be room to integrate it into johnpbloch/wordpress-core-installer

gmazzap commented 8 years ago

I asked Jordi Boggiano if is possible to inject dependencies on the fly and he answered:

not really no, it's possible in a few hacky ways, you might find plugins and traces of attempts here and there, nothing official

Rarst commented 8 years ago

I think you are solving a problem that is both hard to solve and doesn't really need solving.

If the existing site is grown into configuration that is incompatible to Composer then just don't use Composer to manage WP core in that case. It's convenient, not necessary. Legacy sites are by definition inconvenient. So I would question if bending Composer all ways for the sake of edge cases is worth the time that would take to do it robustly and reliably.

Composer can manage dependencies well because it was built for that. WordPress cannot because it was not. By trying to move Composer within constraints of WordPress you compromise what do you need it for in first place — robust dependency management.

dnaber-de commented 8 years ago

Good point @Rarst

schlessera commented 8 years ago

Maybe it would be preferable to have a separate "migration" tool for WP Starter, to migrate an existing WordPress install into a proper WP Starter install.

This way, the existing WP Starter can remain clean and focused, and you don't need to worry about getting that functionality properly hooked into Composer. The tool would just check the current state of the install, and make change/prepare the environment/create a composer.json to be able to normally use WP Starter after that.

gmazzap commented 8 years ago

@Rarst I'm agree with your point, in fact, more than once (last time this morning) I am using Composer to manage dependencies, keeping WordPress core outside of Composer. It is is not very straightforward to do, but the worst part is that the whole process is not easily reproducible (for every website you need a different way) and in best case what you can do is a copy and paste of what you do earlier.

Honestly I don't care to use Composer for WP core or not, what I would like to have is something that:

My first idea was to use Composer because for things that are not core, it has all these features.

If that is not possible / not convient I still need to find a solution. And if came up with a reusable bash script that does the job well enough and can be integrated with Composer (because for plugins I don't want to use anything different) than, it is totally fine.

kraftner commented 8 years ago

@Giuseppe-Mazzapica Just out of curiosity: Can you elaborate what issues you have when migrating away from a default install? If you leave wp-content at the exact location it was and only move core the biggest issue of changed links is non-existent. This worked well for me up until now.

More generally I think @Rarst is right. This is an edge case that isn't really worth wasting time on. @schlessera 's idea of a migration tool sounds better because then you leave that issue behind once and for all.

gmazzap commented 8 years ago

@schlessera The problem with migration is not the environment or the folder structure per se.

The problem is the data. When you have a database with dozen of thousands of posts, each with many images, and paths stored in the database in a recurively serialized fashion in 50 different custom tables... than changing those paths/url in bulk with a script is not something that I would never dare to do.

I would prefer to update my code manually via FTP that do that...

Even because came up with a something capable to do that reliably, and being reusable enough to don't be rewritten from scratch for every website, and robust enough to deal with all the crazy edge cases people have in their servers, that's something I would not be able to do. And I am very fine with that.

Rarst commented 8 years ago

As @kraftner suggested above — leave content in place, move core away (redirect admin to new location) ?

gmazzap commented 8 years ago

With multisite you have issues with content outside "standard" /wp-content, also relative paths stored in database are broken in any case.

franz-josef-kaiser commented 8 years ago

I have to agree with @schlessera that this might be better kept in a separate package. WPStarter can not do everything and this should not be a core responsibility of it. A migration package by itself that covers such use cases is something that I would see as a great enhancement. Still, the idea of having an "adapter-migration-tool" that moves – as @Giuseppe-Mazzapica suggested in his "dream"-description – things into /wp-content would allow to have a first step that prepares the base for a larger migration. My +1 on that.

gmazzap commented 8 years ago

So, I have realized that there's no way to fix this with Composer.

Assuming there would be the possibility to set dependencies on the fly (and it is hackish, but possible), that won't solve the issue.

During a composer update Composer could find that WordPress core needs to be updated, but some plugins don't.

At that point Composer will delete the whole WordPress folder and plugins that don't need to be updated would never be placed there again, because even if Composer understand they depend on WordPress, since they are in their best version, Composer will not attempt to download/clone them again, just assuming they are already in place...

So, in conclusion, I can say that in the cases where plugin/themes really need to be inside WordPress (yes, edge cases), that could easily done with few lines of a bash or a PHP script triggered via Composer script.

I already have such a script, I guess I will create a small Composer plugin to ease its the re-use.