Skip to content
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
28 commits
Select commit Hold shift + click to select a range
8e20aa3
Add classmap output
BrianHenryIE Apr 10, 2020
0ce198d
Missed some copying and pasting
BrianHenryIE Apr 10, 2020
dbeea02
Merge branch 'Regex-fix-for-preceeding-backslash'
BrianHenryIE May 22, 2020
fb75567
Merge branch 'Use-getRealPath-for-symlinked-packages'
BrianHenryIE May 22, 2020
444a32e
Merge branch 'autoload-override'
BrianHenryIE May 22, 2020
7bb930d
Merge branch 'classmap-replacing-in-child-packages'
BrianHenryIE May 22, 2020
e05525c
too much documentation
BrianHenryIE May 22, 2020
8074ed7
too much documentation
BrianHenryIE May 22, 2020
7e929fb
too much documentation
BrianHenryIE May 22, 2020
6e4b3d4
Missed a merge conflict
BrianHenryIE May 22, 2020
6883b58
Update NamespaceReplacer.php
BrianHenryIE May 22, 2020
c7e4b7b
Merge branch 'generate-classmap'
BrianHenryIE May 22, 2020
ad44c39
Update Replacer.php
BrianHenryIE May 22, 2020
3952042
classmap_output example in readme
BrianHenryIE May 22, 2020
8485089
readdme indentation
BrianHenryIE May 22, 2020
0855f17
Merge remote-tracking branch 'upstream/master' into generate-classmap
BrianHenryIE Jun 6, 2020
2ac3d14
removed duplicate doc
BrianHenryIE Jun 6, 2020
1cb6b59
phpcbf
BrianHenryIE Aug 7, 2020
fe32471
undo deleteEmptyDirs merge
BrianHenryIE Aug 7, 2020
5783434
PHPCBF
BrianHenryIE Aug 7, 2020
c99bec5
PHPCS
BrianHenryIE Aug 7, 2020
2dd705c
PHPCBF
BrianHenryIE Aug 7, 2020
10428c7
Merge branch 'master' into generate-classmap
coenjacobs Sep 20, 2020
10dea8b
Merge remote-tracking branch 'upstream/master' into generate-classmap
BrianHenryIE Feb 6, 2021
cb5e5a8
vendor/bin/mozart dump-autoload
BrianHenryIE Feb 7, 2021
7b1c104
Update README.md
BrianHenryIE Feb 7, 2021
b743ce9
Update README.md
BrianHenryIE Feb 7, 2021
ccd0257
Use ob_get_clean() not ob_get_contents()
BrianHenryIE Feb 16, 2021
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
4 changes: 3 additions & 1 deletion README.md
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@ This package requires PHP 7.3 or higher in order to run the tool. You can use th
**Warning:** This package is very experimental and breaking changes are very likely until version 1.0.0 is tagged. Use with caution, always wear a helmet when using this in production environments.

## Installation
Mozart brings its own dependencies to the table and that potentially introduces its own problems (yes, I realise how meta that is, for a package like this). That's why installing Mozart in isolation, either through the Docker container, the available PHAR file or installing Mozart as a global dependency with Composer is prefered. In all cases, the [configuration](#configuration) still needs to be placed in the `composer.json` file of the project iself.
Mozart brings its own dependencies to the table and that potentially introduces its own problems (yes, I realise how meta that is, for a package like this). That's why installing Mozart in isolation, either through the Docker container, the available PHAR file or installing Mozart as a global dependency with Composer is preferred. In all cases, the [configuration](#configuration) still needs to be placed in the `composer.json` file of the project iself.

### Docker
Pull the Docker image from the registry:
Expand Down Expand Up @@ -133,6 +133,8 @@ Mozart is designed to install and be forgotten about. Using Composer scripts, th

When using Mozart through its Docker container, you can replace the `"\"vendor/bin/mozart\" compose",` lines with the actual commands you use to [run the Docker container](#docker) for your specific project. Running Mozart from inside the Docker container is really fast and shouldn't take more than a couple seconds.

If your plugin does not use Composer's autoloader, classmaps can be generated in the `dep_directory` and `classmap_directory` by running `vendor/bin/mozart dump-autoload`

## Background and philosophy
Mozart is designed to bridge the gap between the WordPress ecosytem and the vast packages ecosystem of PHP as a whole. Since WordPress is such an end-user friendly focussed CMS (for good reasons), there is no place within the ecosystem where an end-user would be burdened with using a developers tool like Composer. Also, since WordPress has to run on basically any hosting infrastructure, running Composer to install packages from the administration panel (trust me, I've tried - it can be done) is a mission impossible to make it happen and compatible with every server out there.

Expand Down
1 change: 1 addition & 0 deletions composer.json
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,7 @@
"prefer-stable": true,
"license": "MIT",
"require": {
"composer/composer": "*",
"php": "^7.3|^8.0",
"symfony/console": "^4|^5",
"symfony/finder": "^4|^5",
Expand Down
4 changes: 4 additions & 0 deletions src/Console/Application.php
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@
namespace CoenJacobs\Mozart\Console;

use CoenJacobs\Mozart\Console\Commands\Compose;
use CoenJacobs\Mozart\Console\Commands\DumpAutoload;
use Symfony\Component\Console\Application as BaseApplication;

class Application extends BaseApplication
Expand All @@ -16,5 +17,8 @@ public function __construct($version)

$composeCommand = new Compose();
$this->add($composeCommand);

$dumpAutoloadCommand = new DumpAutoload();
$this->add($dumpAutoloadCommand);
}
}
125 changes: 125 additions & 0 deletions src/Console/Commands/DumpAutoload.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,125 @@
<?php

namespace CoenJacobs\Mozart\Console\Commands;

use Composer\Autoload\ClassMapGenerator;
use Exception;
use Symfony\Component\Console\Command\Command;
use Symfony\Component\Console\Input\InputInterface;
use Symfony\Component\Console\Output\OutputInterface;

class DumpAutoload extends Command
{
private $config;

protected function configure(): void
{
$this->setName('dump-autoload');
$this->setDescription('Generates a classmap from files in the Mozart classmap and dep directories.');
$this->setHelp('');
}

protected function readConfig(): object
{
$workingDir = getcwd();

$composerFile = $workingDir . DIRECTORY_SEPARATOR . 'composer.json';
if (! file_exists($composerFile)) {
throw new Exception('No composer.json found at current directory: ' . $workingDir);
}

$composer = json_decode(file_get_contents($composerFile));
// If the json was malformed.
if (! is_object($composer)) {
throw new Exception('Unable to parse composer.json read at: ' . $workingDir);
}

// if `extra` is missing or not an object or if it does not have a `mozart` key which is an object.
if (! isset($composer->extra) || ! is_object($composer->extra)
|| ! isset($composer->extra->mozart) || ! is_object($composer->extra->mozart)) {
throw new Exception('Mozart config not readable in composer.json at extra->mozart');
}
$config = $composer->extra->mozart;

$config->dep_namespace = preg_replace("/\\\{2,}$/", "\\", "$config->dep_namespace\\");

return $config;
}

protected function execute(InputInterface $input, OutputInterface $output): int
{
try {
$this->config = $this->readConfig();
} catch (Exception $e) {
$output->write($e->getMessage());

return 1;
}

return $this->generateClassmapAutoloader();
}

/**
* Write a classmap to file iun each of the classmap_directory and dep_directory.
*
* Uses Composer's `ClassMapGenerator::createMap()` to scan the directories for classes and generate the map.
*
* createMap() returns the full local path, so we then replace the root of the path with a variable.
*
* @see ClassMapGenerator::dump()
*
*/
private function generateClassmapAutoloader(): int
{

// Hyphen used to match WordPress Coding Standards.
$output_filename = "autoload-classmap.php";

$classmap_directory = getcwd()
. DIRECTORY_SEPARATOR
. ltrim($this->config->classmap_directory, DIRECTORY_SEPARATOR);

$dep_directory = getcwd()
. DIRECTORY_SEPARATOR
. ltrim($this->config->dep_directory, DIRECTORY_SEPARATOR);

$dirs = array(
$classmap_directory,
$dep_directory
);

foreach ($dirs as $dir) {
if (!is_dir($dir)) {
continue;
}

$dirMap = ClassMapGenerator::createMap($dir);

$dirname = preg_replace('/[^a-z]/i', '', str_replace(getcwd(), '', $dir));

array_walk(
$dirMap,
function (&$filepath, $class) use ($dir, $dirname) {
$filepath = "\${$dirname} . '"
. DIRECTORY_SEPARATOR
. ltrim(str_replace($dir, '', $filepath), DIRECTORY_SEPARATOR) . "'";
}
);

ob_start();

echo "<?php\n\n";
echo "// {$output_filename} @generated by Mozart\n\n";
echo "\${$dirname} = dirname(__FILE__);\n\n";
echo "return array(\n";
foreach ($dirMap as $class => $file) {
echo " '{$class}' => {$file},\n";
}
echo ");";

file_put_contents($dir . $output_filename, ob_get_clean());
}

return 0;
}
}