Parcourir la source

Merge remote-tracking branch 'github-beberlei/AutoloadFunctions'

Nils Adermann il y a 12 ans
Parent
commit
8a9c51c83e

+ 13 - 1
doc/04-schema.md

@@ -344,7 +344,7 @@ Example:
 Autoload mapping for a PHP autoloader.
 Autoload mapping for a PHP autoloader.
 
 
 Currently [PSR-0](https://github.com/php-fig/fig-standards/blob/master/accepted/PSR-0.md)
 Currently [PSR-0](https://github.com/php-fig/fig-standards/blob/master/accepted/PSR-0.md)
-autoloading and classmap generation are supported. PSR-0 is the recommended way though
+autoloading, classmap generation and files are supported. PSR-0 is the recommended way though
 since it offers greater flexibility (no need to regenerate the autoloader when you add
 since it offers greater flexibility (no need to regenerate the autoloader when you add
 classes).
 classes).
 
 
@@ -411,6 +411,18 @@ Example:
         }
         }
     }
     }
 
 
+If you want to require certain files explicitly on every request then you can use
+the 'files' autoloading mechanism. This is useful if your package includes PHP functions
+that cannot be autoloaded by PHP.
+
+Example:
+
+    {
+        "autoload": {
+            "files": ["src/MyLibrary/functions.php"]
+        }
+    }
+
 ### include-path
 ### include-path
 
 
 > **DEPRECATED**: This is only present to support legacy projects, and all new code
 > **DEPRECATED**: This is only present to support legacy projects, and all new code

+ 4 - 0
res/composer-schema.json

@@ -135,6 +135,10 @@
                 "classmap": {
                 "classmap": {
                     "type": "array",
                     "type": "array",
                     "description": "This is an array of directories that contain classes to be included in the class-map generation process."
                     "description": "This is an array of directories that contain classes to be included in the class-map generation process."
+                },
+                "files": {
+                    "type": "array",
+                    "description": "This is an array of files that are always required on every request."
                 }
                 }
             }
             }
         },
         },

+ 12 - 3
src/Composer/Autoload/AutoloadGenerator.php

@@ -121,12 +121,19 @@ EOF;
         }
         }
         $classmapFile .= ");\n";
         $classmapFile .= ");\n";
 
 
+        $filesCode          = "";
+        $autoloads['files'] = new \RecursiveIteratorIterator(new \RecursiveArrayIterator($autoloads['files']));
+        foreach ($autoloads['files'] as $functionFile) {
+            $filesCode .= 'require "' . $filesystem->findShortestPath(getcwd(), $functionFile) .'";' . "\n";
+        }
+        $filesCode = rtrim($filesCode);
+
         file_put_contents($targetDir.'/autoload_namespaces.php', $namespacesFile);
         file_put_contents($targetDir.'/autoload_namespaces.php', $namespacesFile);
         file_put_contents($targetDir.'/autoload_classmap.php', $classmapFile);
         file_put_contents($targetDir.'/autoload_classmap.php', $classmapFile);
         if ($includePathFile = $this->getIncludePathsFile($packageMap, $filesystem, $relVendorPath, $vendorPath, $vendorPathCode, $appBaseDirCode)) {
         if ($includePathFile = $this->getIncludePathsFile($packageMap, $filesystem, $relVendorPath, $vendorPath, $vendorPathCode, $appBaseDirCode)) {
             file_put_contents($targetDir.'/include_paths.php', $includePathFile);
             file_put_contents($targetDir.'/include_paths.php', $includePathFile);
         }
         }
-        file_put_contents($vendorPath.'/autoload.php', $this->getAutoloadFile($vendorPathToTargetDirCode, true, true, (Boolean) $includePathFile, $targetDirLoader));
+        file_put_contents($vendorPath.'/autoload.php', $this->getAutoloadFile($vendorPathToTargetDirCode, true, true, (Boolean) $includePathFile, $targetDirLoader, $filesCode));
         copy(__DIR__.'/ClassLoader.php', $targetDir.'/ClassLoader.php');
         copy(__DIR__.'/ClassLoader.php', $targetDir.'/ClassLoader.php');
 
 
         // TODO BC feature, remove after June 15th
         // TODO BC feature, remove after June 15th
@@ -173,7 +180,7 @@ EOF;
      */
      */
     public function parseAutoloads(array $packageMap)
     public function parseAutoloads(array $packageMap)
     {
     {
-        $autoloads = array('classmap' => array(), 'psr-0' => array());
+        $autoloads = array('classmap' => array(), 'psr-0' => array(), 'files' => array());
         foreach ($packageMap as $item) {
         foreach ($packageMap as $item) {
             list($package, $installPath) = $item;
             list($package, $installPath) = $item;
 
 
@@ -281,7 +288,7 @@ EOF;
         return $baseDir.var_export($path, true);
         return $baseDir.var_export($path, true);
     }
     }
 
 
-    protected function getAutoloadFile($vendorPathToTargetDirCode, $usePSR0, $useClassMap, $useIncludePath, $targetDirLoader)
+    protected function getAutoloadFile($vendorPathToTargetDirCode, $usePSR0, $useClassMap, $useIncludePath, $targetDirLoader, $filesCode)
     {
     {
         $file = <<<HEADER
         $file = <<<HEADER
 <?php
 <?php
@@ -291,6 +298,8 @@ if (!class_exists('Composer\\\\Autoload\\\\ClassLoader', false)) {
     require $vendorPathToTargetDirCode . '/ClassLoader.php';
     require $vendorPathToTargetDirCode . '/ClassLoader.php';
 }
 }
 
 
+$filesCode
+
 return call_user_func(function() {
 return call_user_func(function() {
     \$loader = new \\Composer\\Autoload\\ClassLoader();
     \$loader = new \\Composer\\Autoload\\ClassLoader();
     \$composerDir = $vendorPathToTargetDirCode;
     \$composerDir = $vendorPathToTargetDirCode;

+ 31 - 0
tests/Composer/Test/Autoload/AutoloadGeneratorTest.php

@@ -251,6 +251,37 @@ class AutoloadGeneratorTest extends TestCase
         $this->assertAutoloadFiles('classmap5', $this->vendorDir.'/composer', 'classmap');
         $this->assertAutoloadFiles('classmap5', $this->vendorDir.'/composer', 'classmap');
     }
     }
 
 
+    public function testFilesAutoloadGeneration()
+    {
+        $package = new MemoryPackage('a', '1.0', '1.0');
+
+        $packages = array();
+        $packages[] = $a = new MemoryPackage('a/a', '1.0', '1.0');
+        $packages[] = $b = new MemoryPackage('b/b', '1.0', '1.0');
+        $a->setAutoload(array('files' => array('test.php')));
+        $b->setAutoload(array('files' => array('test2.php')));
+
+        $this->repository->expects($this->once())
+            ->method('getPackages')
+            ->will($this->returnValue($packages));
+
+        mkdir($this->vendorDir.'/a/a', 0777, true);
+        mkdir($this->vendorDir.'/b/b', 0777, true);
+        file_put_contents($this->vendorDir.'/a/a/test.php', '<?php function testFilesAutoloadGeneration1() {}');
+        file_put_contents($this->vendorDir.'/b/b/test2.php', '<?php function testFilesAutoloadGeneration2() {}');
+
+        $this->generator->dump($this->repository, $package, $this->im, $this->vendorDir.'/composer');
+
+        $code = file_get_contents($this->vendorDir.'/autoload.php');
+        $this->assertContains('a/a/test.php', $code);
+        $this->assertContains('b/b/test2.php', $code);
+
+        include $this->vendorDir . '/autoload.php';
+
+        $this->assertTrue(function_exists('testFilesAutoloadGeneration1'));
+        $this->assertTrue(function_exists('testFilesAutoloadGeneration2'));
+    }
+
     public function testOverrideVendorsAutoloading()
     public function testOverrideVendorsAutoloading()
     {
     {
         $package = new MemoryPackage('a', '1.0', '1.0');
         $package = new MemoryPackage('a', '1.0', '1.0');

+ 2 - 0
tests/Composer/Test/Autoload/Fixtures/autoload_target_dir.php

@@ -5,6 +5,8 @@ if (!class_exists('Composer\\Autoload\\ClassLoader', false)) {
     require __DIR__ . '/composer' . '/ClassLoader.php';
     require __DIR__ . '/composer' . '/ClassLoader.php';
 }
 }
 
 
+
+
 return call_user_func(function() {
 return call_user_func(function() {
     $loader = new \Composer\Autoload\ClassLoader();
     $loader = new \Composer\Autoload\ClassLoader();
     $composerDir = __DIR__ . '/composer';
     $composerDir = __DIR__ . '/composer';