Can i use PSRs in wordpress vs the WordPress Coding Standards?
I am going to create a plugin but I want to use psrs and take advantage of all its features.
psr4
libs
Absolutely, and it is best to use it for plugin development.
But as you know it is not recommended by the wordpress community one reason is it can be problematic if other plugins or the theme share identical packages installed via composer
But to use PSR4 or somthing similar just start your project with a composer.json and structure it with the correct file path for development for your plugin. Look at the example snippet below declaring autoload in composer.json followed by the PSR and the path
EXAMPLE: composer.json
{
"name": "author/myplugin",
"type": "wordpress-plugin",
"description": "Description",
"require": {
"php": ">=7.4"
},
"autoload": {
"psr-4": {
"MYPLUGIN\\": "src/Includes/"
}
}
}
I have a number of private, custom bundles that I use in my Symfony projects. Under Symfony 3, they lived in a sub-directory of src:
src/
DSL/
DSLLibraryBundle/
DSLTelnetBundle/
...
SiteBundle/ # (or AppBundle)
Under Symfony 4, the application-specific bundle is gone and it's unclear to me where my custom bundles should live.
The documentation on bundles (https://symfony.com/doc/current/bundles/best_practices.html#bundles-naming-conventions) provide no specific recommendations for placing custom bundles.
I have tried placing my DSL directory directly under the project directory and under src/. I end up with undefined class errors either way.
I currently have:
src/
DSL/
LibraryBundle/
DSLLibraryBundle.php
The bundle file:
// src/DSL/DSLLibrary/DSLLibraryBundle.php:
namespace DSL\LibraryBundle;
use Symfony\Component\HttpKernel\Bundle\Bundle;
class DSLLibraryBundle extends Bundle
{
}
The entry in bundles.php:
DSL\LibraryBundle\DSLLibraryBundle::class => ['all' => true],
Current error when running a console command:
PHP Fatal error: Uncaught
Symfony\Component\Debug\Exception\ClassNotFoundException: Attempted to
load class "DSLLibraryBundle" from namespace "DSL\LibraryBundle".
A couple of notes:
- My custom bundles are not installed via Composer
- The actual DSL/ directory will be a symlink once I get this working
Update April 12, 2019:
In the end, I took a completely different approach than my initial attempts.
In a nutshell, I now use composer to include my custom bundles.
My custom bundles live in their own directory tree.
Each bundle must have a valid composer.json file defining the bundle. For example:
{
"name": "dsl/base-bundle",
"description": "Base bundle required by all other DSL bundles",
"type": "symfony-bundle",
"version": "2.1.0",
"license": "proprietary",
"authors": [{"name": "David M. Patterson", "email": "dpatterson#example.com"}],
"minimum-stability": "stable",
"require": {
},
"require-dev": {
},
"autoload": {
"psr-4": {
"Dsl\\BaseBundle\\": "src/"
}
}
}
Then define a custom repository in the project's composer.json file:
"repositories":[
{
"type": "path",
"url": "/full/path/to/DslBaseBundle"
},
], ...
Then do a composer require dsl/base-bundle
Composer will create a symlink in vendor/ to the bundle and everything works as expected from there on.
My personal library is a regular Symfony project with a lib sub-directory that contains my bundles, each in its own sub-directory below lib/.
The Symfony application provides me with a convenient test bed. Note that the custom bundles must be included in it the same as for any other Symfony project.
#Stnaire, hope that helps.
It's actually not as bad as it's painted in other comments - you can still have your private bundles inside src/, you just have to explicitly exclude them from autowiring, so they don't get accidentally loaded with an incorrect namespace.
Lets say you have a PrivateBundle in src/PrivateBundle.
You set up it's autoloading in composer.json like so:
"autoload": {
"psr-4": {
"App\\": "src/",
"SomeNamespace\\PrivateBundle\\": "src/PrivateBundle/"
}
}
and in your services configuration (I usually use config/services.yaml) do this:
# makes classes in src/ available to be used as services
# this creates a service per class whose id is the fully-qualified class name
App\:
resource: '../src/*'
exclude: '../src/PrivateBundle'
If you don't add this exclude, your SomeNamespace\PrivateBundle\* classes get automatically loaded by Symfony as App\PrivateBundle\*, but contain namespace SomeNamespace\PrivateBundle;, so when PHP detects a usage of SomeNamespace\PrivateBundle it autoloads them again through Composer, resulting in Cannot declare class *, because the name is already in use errors.
Update 30-Jan-2017:
Okay. As far as I can tell, Symfony 4 is, effectively, private bundle hostile.
Additional work just kept turning up more and more problems (like getting unit testing to work for a private bundle).
I am currently pursuing other options that won't result in too much additional daily work.
Please ignore my original answer below.
--
My original answer:
After some more digging I realized that the classes in my custom bundle directory tree were not being picked up by composer during dump-autoload.
I think this is because Symfony 4 is not expecting any bundles except in vendor/.
The solution was to add my library directory to composer.json.
So My project tree now contains a directory for my private, custom bundles.
<projectName>/
assets/
...
DSL/
DSLLibraryBundle/
DSLTelnetBundle/
...
public/
src/
...
My composer.json autoload.psr-4 entry now looks like this:
"autoload": {
"psr-4": {
"App\\": "src/",
"DSL\\": "DSL/"
}
},
Symfony4 no longer uses bundles inside the src/ . Bundles are only used within vendor/ as dependencies.
I'm using Roots/Bedrock for my WordPress structure and I want to use WebDevStudios/CMB2 as a library and not as a plugin.
The Roots/Bedrock composer.json specifies that dependencies of type:wordpress-plugin be installed in app/plugins. The WebDevStudios/CMB2 composer.json declares that it is a wordpress-plugin type, so it gets installed into app/plugins which is not where I want it.
How can I get this dependency to be installed into vendor and not app/plugins?
I have a suspicion I might have to fork CMB2 and change it's type from wordpress-plugin to library, but I'm hoping there is a cleaner solution.
I'm not using Roots/Bedrock but I had a similar problem when adding CMB2 as a dependency to a plugin (rather than loading it as a separate plugin). It was installing the plugin in wp-content/plugins instead of vendor. The following worked for me.
{
"require": {
"webdevstudios/cmb2": "^2.2",
},
"autoload" : {
"files": [
"vendor/webdevstudios/cmb2/init.php"
]
},
"extra": {
"installer-paths": {
"vendor/webdevstudios/cmb2": ["webdevstudios/cmb2"]
}
}
}
The key was the installer-paths entry that tells Composer where we want to install webdevstudios/cmb2.
I wrote a blog post about this at https://salferrarello.com/cmb2-composer-dependency/
I want to include normal php script that I have made before for another project in DefaultController.
public function indexAction()
{
include('./GenFunctions.php');
then I put GenFunctinos.php in the same directory as DefaultController,
but it shows 'failed to open stream'
How can I include this script?
I understood this is the illegular way to include in the perspective of symfony2.
But I want to do this to reuse the script.
please help me.
You can autoload this file with composer.
http://getcomposer.org/doc/04-schema.md#files
{
"autoload": {
"files": ["src/GenFunctions.php"]
}
}
With Symfony 2.0.x I store all my client side dependencies (jQuery, etc) in the deps file so I can easily update them all at once with vendor/install, with the switch to composer in 2.1 this is not possible. My options appear to be:
Fork all repos and add in the composer.json file (pain in the butt and waste of time)
Manually download them all and stick them inside my repo somewhere (also a pain in the butt)
Write my own Grunt script or something similar
Does anyone have a solution for handling this, or am I going about it all wrong?
Composer does have support for downloading libraries that are not Composer-aware. It's a little more work, but you can define each of your dependencies like this:
{
"repositories": [
{
"type": "package",
"package": {
"name": "jquery/jquery",
"version": "1.8.1",
"dist": {
"url": "http://code.jquery.com/jquery-1.8.1.min.js",
"type": "file"
}
}
}
],
"require": {
"jquery/jquery": "1.8.1"
}
}
Read more about it here: http://getcomposer.org/doc/05-repositories.md#package-2.
This will download jQuery to vendors/jquery/jquery by default. I don't think there's a way to specify a directory outside of vendors at the moment, so that may considerably limit the usefulness of this suggestion.
FWIW, I would consider submitting a pull request/issue to the Composer Github project. This actually would make a whole lot of sense.