wp-oop / plugin-boilerplate

A project skeleton useful for starting a new WordPress plugin
GNU General Public License v2.0
20 stars 5 forks source link

PhpStorm WordPress Integration #25

Open kraftner opened 3 years ago

kraftner commented 3 years ago

The WP integration of PhpStorm seems to require a local path to WP. But you bake WP into the container which prevents that from working. So you either don't use it or need to have WP core somewhere else on the machine.

Personally I find this useful especially for the hooks integration.

Generally having WP Core hidden in the Container also makes other things difficult like stepping through core with xDebug or working on core itself.

Personally I have often turned to not baking WP into the container for this reason but install it with Composer in the host filesystem and mount it into the container. But this of course comes with other disadvantages like e.g. the usual permission issues with docker mounts.

Curious about your thoughts on this.

XedinUnknown commented 3 years ago

Hi! Thanks for reporting this!

Yes, you're right: the WP files are only actually available inside the container. But the WordPress integration does not require WP to be under the project root - it can be literally anywhere within the local filesystem.

Here is how the features of the PHPStorm + WP integration compare IMHO to what there is already:

As for using xDebug to step through WP itself e.g. to debug a request, yes, that would be very useful. But there were just so many problems with this approach, and using the official Docker image for this is just way, way simpler. I myself have adopted an IMHO cleaner approach based on my philosophy: if I am not working on some code, then I should not debug that code. But I see how it can sometimes be useful, knowing how WordPress is.

Perhaps, it could be possible to share the files from the container into a sub-directory of the project, and kill two birds with one stone? I really wouldn't want to go back to mounting the WP files from the host, but another approach alongside the main one wouldn't hurt to cover this case.

kraftner commented 3 years ago

I agree that using the official Docker image has its merits. Can you elaborate what you mean by "share the files from the container into a sub-directory of the project" if not "mounting the WP files from the host".

I've also experimented with using the docker image, but having WP core in the project, e.g. as a composer dev dependency, and using that for the integration. But it feels messy treating something as the code used if it in really isn't. I've ended forgetting about this multiple times, messing with core files to debug an issue and wasting plenty of times until remembering that this core isn't the one the container actually runs of. So this feels fragile too.

I know this is a tricky one where one would probably end up with a compromise one way or the other, I was just curious about different approaches I might have missed as well as arguments for and against various approaches.

XedinUnknown commented 3 years ago

Can you elaborate what you mean by "share the files from the container into a sub-directory of the project" if not "mounting the WP files from the host".

I mean something that would make it work the other way. Which should be quite possible, since WP is installed at runtime via the entrypoint, and if you mount that directory from the host, it should get filled up with WP files on our host machine. Or something similar.

I know this is a tricky one where one would probably end up with a compromise one way or the other

I don't think it's necessary to choose. It shouldn't be that hard to change this specific part of the setup to tailor to your needs. And if the approach to that is documented somewhere here, then perhaps it's a viable option for many other people too.

kraftner commented 3 years ago

I mean something that would make it work the other way. Which should be quite possible, since WP is installed at runtime via the entrypoint, and if you mount that directory from the host, it should get filled up with WP files on our host machine. Or something similar.

Oh, that sounds like an interesting idea. See, that is why bouncing ideas is great! :grinning:

I can imagine one might also run into permission issues with that, but I'll definitely try it. I'll report back.

XedinUnknown commented 3 years ago

I can imagine one might also run into permission issues with that

I'm much more afraid of cross-mounting issues, which cannot just be remedied by chowning en-masse.

I'll definitely try it. I'll report back.

Thank you!

kraftner commented 3 years ago

Okay so I just tried this in a basic proof of concept.

    test:
        image: wordpress:latest
        volumes:
            - ./wordpress:/var/www/html

This installs WP and puts the files in the host filesystem. But since the folder didn't exist it is owned by root which sucks on the host. So I created an empty folder wordpress. WP gets installed fine again, but the wordpress folder now is owned by www-data. Same issue bascially.

So I then did set a user.

    test:
        image: wordpress:latest
        user: 1000:1000
        volumes:
            - ./wordpress:/var/www/html

Now this works and puts WP core on the host filesystem where PhpStorm can find it.

Minor issue: For changing the WP version one needs to manually empty the wordpress folder. Maybe this could also be automated by checking the version in the entrypoint and removing WP if there is a mismatch. Haven't thought this through yet though.

kraftner commented 3 years ago

Okay I went further, now mounting the plugin into WP too.

test:
    image: wordpress:latest
    user: 1000:1000
    volumes:
        - ./wordpress:/var/www/html
        - .:/var/www/html/wp-content/plugins/plugin-name

But now another problem arises, being that we now have nested mounts, which causes a stray root-owned folder being created in wordpress/wp-content/ on the host and according to https://github.com/moby/moby/issues/26051 this is just how things work.

Again, this can be worked around by creating wordpress/wp-content/plugins/plugin-name in advance. But now this whole thing starts to feel quite fragile...

kraftner commented 3 years ago

Ok this is what I've settled with for now. It works for me but I am not sure it is clean enough to be included in a public thing.

test:
    image: wordpress:latest
    # When using a custom container definition this could also be put there, maybe with a build arg.
    user: 1000:1000
    volumes:
        # Mount the plugin into WP core
        - type: bind
          source: .
          target: /var/www/html/wp-content/plugins/plugin-name
        # If you don't want to have WP core in the local filesystem just comment out the rest of the volumes
        - type: bind
          source: ./wordpress
          target: /var/www/html
        # This is just a guard that aborts if the mount folder for the plugin doesn't exist.
        # This keeps Docker from creating a root-owned folder in the host file system.
        # This only works with the long form mount definition. Only missing `source` causes an error.
        # https://docs.docker.com/storage/bind-mounts/#differences-between--v-and---mount-behavior
        - type: bind
          source: ./wordpress/wp-content/plugins/plugin-name
          target: /tmp/foo

What do you think @XedinUnknown ?

XedinUnknown commented 1 year ago

The project includes php-stubs/wordpress-stubs, which contains all of the WP function and class etc. definitions. Psalm, PHPStorm, and other tools should be able to see that, if you point them to it.

Does this solve the problem?