Author: Derick Rethans
Date: 2006-11-17 14:06:33 +0100 (Fri, 17 Nov 2006)
New Revision: 3958

Log:
- Fixed issue #9390: Classes in external repositories that map to the same
  autoload filename of an internal component where added to the external
  autoload cache array as well.
- Fixed issue #8507: Two autoload directories with the same basepath don't
  work.
- Added some additional test cases.

Added:
   trunk/Base/src/exceptions/double_class_repository_prefix.php
   trunk/Base/tests/extra_repository/
   trunk/Base/tests/extra_repository/Translation/
   trunk/Base/tests/extra_repository/Translation/test.php
   trunk/Base/tests/extra_repository/autoload/
   trunk/Base/tests/extra_repository/autoload/translation_autoload.php
   trunk/Base/tests/test_repository/TestClasses/base_test_long_class.php
   trunk/Base/tests/test_repository/autoload_files/basetest_long_autoload.php
Modified:
   trunk/Base/ChangeLog
   trunk/Base/src/base.php
   trunk/Base/src/base_autoload.php
   trunk/Base/tests/base_test.php
   trunk/Base/tests/test_repository/autoload_files/basetest_autoload.php

Modified: trunk/Base/ChangeLog
===================================================================
--- trunk/Base/ChangeLog        2006-11-17 12:57:12 UTC (rev 3957)
+++ trunk/Base/ChangeLog        2006-11-17 13:06:33 UTC (rev 3958)
@@ -1,3 +1,13 @@
+1.2beta2 - [RELEASEDATE]
+^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+
+- Fixed issue #9390: Classes in external repositories that map to the same
+  autoload filename of an internal component where added to the external
+  autoload cache array as well.
+- Fixed issue #8507: Two autoload directories with the same basepath don't
+  work.
+
+
 1.2beta1 - Tuesday 24 October 2006
 ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
 

Modified: trunk/Base/src/base.php
===================================================================
--- trunk/Base/src/base.php     2006-11-17 12:57:12 UTC (rev 3957)
+++ trunk/Base/src/base.php     2006-11-17 13:06:33 UTC (rev 3958)
@@ -42,10 +42,14 @@
     protected static $packageDir;
 
     /**
-     * @var array(string->array) Stores info with additional paths where
+     * @var array(string=>array) Stores info with additional paths where
      *                           autoload files and classes for autoloading
      *                           could be found.  Each item of $repositoryDirs
      *                           looks like array( autoloadFileDir, baseDir ).
+     *                           The array key is the prefix belonging to
+     *                           classes within that repository - if provided
+     *                           when calling addClassRepository(), or an
+     *                           autoincrement integer otherwise.
      */
     protected static $repositoryDirs = array();
 
@@ -93,7 +97,7 @@
         }
         
         // Check whether the classname is already in the cached autoloadArray
-        // for external repositories..
+        // for external repositories.
         if ( array_key_exists( $className, ezcBase::$externalAutoloadArray ) )
         {
             // Is it registered as 'unloadable'?
@@ -109,25 +113,25 @@
         // Not cached, so load the autoload from the package.
         // Matches the first and optionally the second 'word' from the 
classname.
         $fileNames = array();
-        if ( preg_match( "/^[a-z]*([A-Z][a-z0-9]*)([A-Z][a-z0-9]*)?/", 
$className, $matches ) !== false )
+        if ( preg_match( "/^([a-z]*)([A-Z][a-z0-9]*)([A-Z][a-z0-9]*)?/", 
$className, $matches ) !== false )
         {
             $autoloadFile = "";
             // Try to match with both names, if available.
             switch ( sizeof( $matches ) )
             {
-                case 3:
-                    $autoloadFile = strtolower( 
"{$matches[1]}_{$matches[2]}_autoload.php" );
+                case 4:
+                    $autoloadFile = strtolower( 
"{$matches[2]}_{$matches[3]}_autoload.php" );
                     $fileNames[] = $autoloadFile;
-                    if ( ezcBase::requireFile( $autoloadFile, $className ) )
+                    if ( ezcBase::requireFile( $autoloadFile, $className, 
$matches[1] ) )
                     {
                         return true;
                     }
                     // break intentionally missing.
 
-                case 2:
-                    $autoloadFile = strtolower( "{$matches[1]}_autoload.php" );
+                case 3:
+                    $autoloadFile = strtolower( "{$matches[2]}_autoload.php" );
                     $fileNames[] = $autoloadFile;
-                    if ( ezcBase::requireFile( $autoloadFile, $className ) )
+                    if ( ezcBase::requireFile( $autoloadFile, $className, 
$matches[1] ) )
                     {
                         return true;
                     }
@@ -143,6 +147,8 @@
         $realPath = realpath( $path );
         if ( $realPath == '' )
         {
+            // Can not be tested, because if this happens, then the autoload
+            // environment has not been set-up correctly. 
             trigger_error( "Couldn't find autoload directory '$path'", 
E_USER_ERROR );
         }
         /* FIXME: this should go away - only for development */
@@ -203,14 +209,14 @@
      * @return bool  True is returned when the file is correctly loaded.
      *                   Otherwise false is returned.
      */
-    protected static function requireFile( $fileName, $className )
+    protected static function requireFile( $fileName, $className, $prefix )
     {
         $autoloadDir = ezcBase::$packageDir . "autoload/";
         
         // We need the full path to the fileName. The method file_exists() 
doesn't
         // automatically check the (php.ini) library paths. Therefore:
         // file_exists( "ezc/autoload/$fileName" ) doesn't work.
-        if ( file_exists( "$autoloadDir$fileName" ) )
+        if ( $prefix === 'ezc' && file_exists( "$autoloadDir$fileName" ) )
         {
             $array = require( "$autoloadDir$fileName" );
 
@@ -225,10 +231,16 @@
 
         // It is not in components autoload/ dir.
         // try to search in additional dirs.
-        foreach ( ezcBase::$repositoryDirs as $extraDir )
+        foreach ( ezcBase::$repositoryDirs as $repositoryPrefix => $extraDir )
         {
+            if ( gettype( $repositoryPrefix ) === 'string' && 
$repositoryPrefix !== $prefix )
+            {
+                continue;
+            }
+
             if ( file_exists( $extraDir['autoloadDirPath'] . '/' . $fileName ) 
)
             {
+                $array = array();
                 $originalArray = require( $extraDir['autoloadDirPath'] . '/' . 
$fileName );
 
                 // Building paths.
@@ -298,6 +310,8 @@
         }
         else
         {
+            // Can not be tested, because if this happens, then one of the
+            // components has a broken autoload file.
             throw new ezcBaseFileNotFoundException( ezcBase::$packageDir.$file 
);
         }
     }
@@ -341,6 +355,7 @@
                 }
                 else
                 {
+                    // Can not be tested as it would abort the PHP script.
                     die( "\nThe {$component} component depends on the default 
PHP extension '{$value}', which is not loaded.\n" );
                 }
                 break;
@@ -353,6 +368,7 @@
                 }
                 else
                 {
+                    // Can not be tested as it would abort the PHP script.
                     die( "\nThe {$component} component depends on the PHP 
version '{$value}', but the current version is '{$phpVersion}'.\n" );
                 }
                 break;
@@ -376,7 +392,7 @@
         $autoloadDirs = array();
         ezcBase::setPackageDir();
         $repositoryDir = self::$currentWorkingDirectory ? 
self::$currentWorkingDirectory : ( realpath( dirname( __FILE__ ) . '/../../' ) 
);
-        $autoloadDirs[$repositoryDir] = array( 'ezc', $repositoryDir . 
"/autoload" );
+        $autoloadDirs['ezc'] = array( 'ezc', $repositoryDir . "/autoload" );
 
         foreach ( ezcBase::$repositoryDirs as $extraDirKey => $extraDirArray )
         {
@@ -447,7 +463,7 @@
      * ./repos/You/yourclass1.php
      * ./repos/You/yourclass2.php
      * </code>
-
+     *
      * To use this repository with the autoload mechanism you have to use the
      * following code:
      * <code>
@@ -461,7 +477,7 @@
      * @param string $autoloadDirPath
      * @param string $basePath
      */
-    public static function addClassRepository( $basePath, $autoloadDirPath = 
null )
+    public static function addClassRepository( $basePath, $autoloadDirPath = 
null, $prefix = null )
     {
         // check if base path exists
         if ( !is_dir( $basePath ) ) 
@@ -482,11 +498,23 @@
         }
 
         // add info to $repositoryDirs
-        // $autoloadDirPath will be used as a key in $repositoryDirs
-        $array = array( $basePath => array( 'basePath' => $basePath, 
'autoloadDirPath' => $autoloadDirPath ) );
-
-        // add info to the list of extra dirs if it exists there it will not 
be doubled.
-        ezcBase::$repositoryDirs = array_merge( ezcBase::$repositoryDirs, 
$array );
+        if ( $prefix === null )
+        {
+            $array = array( 'basePath' => $basePath, 'autoloadDirPath' => 
$autoloadDirPath );
+ 
+            // add info to the list of extra dirs
+            ezcBase::$repositoryDirs[] = $array;
+        }
+        else
+        {
+            if ( array_key_exists( $prefix, ezcBase::$repositoryDirs ) )
+            {
+                throw new ezcBaseDoubleClassRepositoryPrefix( $prefix, 
$basePath, $autoloadDirPath );
+            }
+ 
+            // add info to the list of extra dirs, and use the prefix to 
identify the new repository.
+            ezcBase::$repositoryDirs[$prefix] = array( 'basePath' => 
$basePath, 'autoloadDirPath' => $autoloadDirPath );
+        }
     }
 }
 ?>

Modified: trunk/Base/src/base_autoload.php
===================================================================
--- trunk/Base/src/base_autoload.php    2006-11-17 12:57:12 UTC (rev 3957)
+++ trunk/Base/src/base_autoload.php    2006-11-17 13:06:33 UTC (rev 3958)
@@ -17,6 +17,7 @@
     'ezcBaseException'                     => 'Base/exceptions/exception.php',
     'ezcBaseFileException'                 => 
'Base/exceptions/file_exception.php',
 
+    'ezcBaseDoubleClassRepositoryPrefix'   => 
'Base/exceptions/double_class_repository_prefix.php',
     'ezcBaseFileNotFoundException'         => 
'Base/exceptions/file_not_found.php',
     'ezcBaseFileIoException'               => 'Base/exceptions/file_io.php',
     'ezcBaseFilePermissionException'       => 
'Base/exceptions/file_permission.php',

Added: trunk/Base/src/exceptions/double_class_repository_prefix.php
===================================================================
--- trunk/Base/src/exceptions/double_class_repository_prefix.php        
2006-11-17 12:57:12 UTC (rev 3957)
+++ trunk/Base/src/exceptions/double_class_repository_prefix.php        
2006-11-17 13:06:33 UTC (rev 3958)
@@ -0,0 +1,28 @@
+<?php
+/**
+ * File containing the ezcBaseDoubleClassRepositoryPrefix class
+ *
+ * @package Base
+ * @version //autogen//
+ * @copyright Copyright (C) 2005, 2006 eZ systems as. All rights reserved.
+ * @license http://ez.no/licenses/new_bsd New BSD License
+ */
+/**
+ * ezcBaseDoubleClassRepositoryPrefix is thrown whenever you try to register a
+ * class repository with a prefix that has already been added before.
+ *
+ * @package Base
+ * @version //autogen//
+ */
+class ezcBaseDoubleClassRepositoryPrefix extends ezcBaseException
+{
+    /**
+     * Constructs a new ezcBaseDoubleClassRepositoryPrefix for the $prefix that
+     * points to $basePath with autoload directory $autoloadDirPath.
+     */
+    function __construct( $prefix, $basePath, $autoloadDirPath )
+    {
+        parent::__construct( "The class repository in <{$basePath}> (with 
autoload dir <{$autoloadDirPath}>) can not be added because another class 
repository already uses the prefix <{$prefix}>." );
+    }
+}
+?>


Property changes on: 
trunk/Base/src/exceptions/double_class_repository_prefix.php
___________________________________________________________________
Name: svn:eol-style
   + native

Modified: trunk/Base/tests/base_test.php
===================================================================
--- trunk/Base/tests/base_test.php      2006-11-17 12:57:12 UTC (rev 3957)
+++ trunk/Base/tests/base_test.php      2006-11-17 13:06:33 UTC (rev 3958)
@@ -53,6 +53,18 @@
         }
     }
 
+    public function testConfigExceptionOutOfRange3()
+    {
+        try
+        {
+            throw new ezcBaseSettingValueException( 'broken', array(1, 1, 3, 
4, 5), 'int' );
+        }
+        catch ( ezcBaseSettingValueException $e )
+        {
+            $this->assertEquals( "The value 
<a:5:{i:0;i:1;i:1;i:1;i:2;i:3;i:3;i:4;i:4;i:5;}> that you were trying to assign 
to setting <broken> is invalid. Allowed values are: int", $e->getMessage() );
+        }
+    }
+
     public function testFileIoException1()
     {
         try
@@ -185,6 +197,18 @@
         }
     }
 
+    public function testFilePermissionException6()
+    {
+        try
+        {
+            throw new ezcBaseFilePermissionException( 'testfile.php', 
ezcBaseFilePermissionException::REMOVE, "Extra extra" );
+        }
+        catch ( ezcBaseException $e )
+        {
+            $this->assertEquals( "The file <testfile.php> can not be removed. 
(Extra extra)", $e->getMessage() );
+        }
+    }
+
     public function testPropertyNotFoundException()
     {
         try
@@ -280,18 +304,18 @@
             $this->fail( "Duplicating or missing extra autoload dirs while 
adding." );
         }
 
-        $packageDir = realpath( dirname( __FILE__ ) . '/../..' );
-        if ( !isset( $resultArray[$packageDir] ) ) 
+        if ( !isset( $resultArray['ezc'] ) ) 
         {
            $this->fail( "No packageDir found in result of 
getRepositoryDirectories()" );
         }
 
-        if ( !isset( $resultArray['.'] ) || $resultArray['.'][1] != 
'./autoload' )
+        if ( !isset( $resultArray[0] ) || $resultArray[0][1] != './autoload' )
         {
             $this->fail( "Extra autoload dir <{$resultArray['.'][1]}> is added 
incorrectly" );
         }
     }
 
+    // this test is sorta obsolete, but we keep it around for good measure
     public function testBaseAddAndGetAutoloadDirs2()
     {
         ezcBase::addClassRepository( '.', './autoload' );
@@ -299,37 +323,89 @@
         ezcBase::addClassRepository( './Base/tests/test_repository', 
'./Base/tests/test_repository/autoload_files' );
         $resultArray = ezcBase::getRepositoryDirectories();
 
-        if ( count( $resultArray ) != 3 ) 
+        if ( count( $resultArray ) != 5 ) 
         {
             $this->fail( "Duplicating or missing extra autoload dirs while 
adding." );
         }
 
-        $packageDir = realpath( dirname( __FILE__ ) . '/../..' );
-        if ( !isset( $resultArray[$packageDir] ) ) 
+        if ( !isset( $resultArray['ezc'] ) ) 
         {
            $this->fail( "No packageDir found in result of 
getRepositoryDirectories()" );
         }
 
-        if ( !isset( $resultArray['./Base/tests/test_repository'] ) || 
$resultArray['./Base/tests/test_repository'][1] != 
'./Base/tests/test_repository/autoload_files' )
+        if ( !isset( $resultArray[2] ) || $resultArray[2][1] != 
'./Base/tests/test_repository/autoload_files' )
         {
-            $this->fail( "Extra autoload dir 
<{$resultArray['./Base/tests/test_repository'][1]}> is added incorrectly" );
+            $this->fail( "Extra autoload dir <{$resultArray[2][1]}> is added 
incorrectly" );
         }
 
         self::assertEquals( true, class_exists( 'trBasetestClass', true ) );
         self::assertEquals( true, class_exists( 'trBasetestClass2', true ) );
         self::assertEquals( false, @class_exists( 'trBasetestClass3', true ) );
+        self::assertEquals( true, class_exists( 'trBasetestLongClass', true ) 
);
+
+        try
+        {
+            class_exists( 'trBasetestClass4', true );
+            self::fail( 'The expected exception was not thrown.' );
+        }
+        catch ( ezcBaseFileNotFoundException $e )
+        {
+            self::assertEquals( 'The file 
<./Base/tests/test_repository/TestClasses/base_test_class_number_four.php> 
could not be found.', $e->getMessage() );
+        }
     }
 
+    public function testBaseAddAndGetAutoloadDirs3()
+    {
+        ezcBase::addClassRepository( './Base/tests/extra_repository', null, 
'ext' );
+
+        $resultArray = ezcBase::getRepositoryDirectories();
+        self::assertEquals( true, array_key_exists( 'ezc', $resultArray ) );
+        self::assertEquals( true, array_key_exists( 'ext', $resultArray ) );
+
+        self::assertEquals( true, class_exists( 'extTranslationTest', true ) );
+        self::assertEquals( true, class_exists( 'ezcTranslationTsBackend', 
true ) );
+    }
+
+    public function testBaseAddAndGetAutoloadDirs4()
+    {
+        ezcBase::addClassRepository( './Base/tests/test_repository', 
'./Base/tests/test_repository/autoload_files', 'tr' );
+
+        try
+        {
+            ezcBase::addClassRepository( './Base/tests/test_repository', 
'./Base/tests/test_repository/autoload_files', 'tr' );
+        }
+        catch ( ezcBaseDoubleClassRepositoryPrefix $e )
+        {
+            self::assertEquals( 'The class repository in 
<./Base/tests/test_repository> (with autoload dir 
<./Base/tests/test_repository/autoload_files>) can not be added because another 
class repository already uses the prefix <tr>.', $e->getMessage() );
+        }
+
+        $resultArray = ezcBase::getRepositoryDirectories();
+        self::assertEquals( 7, count( $resultArray ) );
+
+        self::assertEquals( true, array_key_exists( 'ezc', $resultArray ) );
+        self::assertEquals( true, array_key_exists( 'tr', $resultArray ) );
+    }
+
     public function testNoPrefixAutoload()
     {
         ezcBase::addClassRepository( './Base/tests/test_repository', 
'./Base/tests/test_repository/autoload_files' );
         __autoload( 'Object' );
-        if( !class_exists( 'Object' ) )
+        if ( !class_exists( 'Object' ) )
         {
             $this->fail( "Autoload does not handle classes with no prefix" );
         }
     }
 
+    public function testCheckDependencyExtension()
+    {
+        ezcBase::checkDependency( 'Tester', ezcBase::DEP_PHP_EXTENSION, 
'standard' );
+    }
+
+    public function testCheckDependencyVersion()
+    {
+        ezcBase::checkDependency( 'Tester', ezcBase::DEP_PHP_VERSION, '5.1.1' 
);
+    }
+
     public function testInvalidClass()
     {
         set_error_handler( array( $this, "ErrorHandlerTest" ) );
@@ -351,7 +427,7 @@
     {
         $this->errorMessage = $errstr;
     }
-    
+
     public static function suite()
     {
         return new PHPUnit_Framework_TestSuite("ezcBaseTest");

Added: trunk/Base/tests/extra_repository/Translation/test.php
===================================================================
--- trunk/Base/tests/extra_repository/Translation/test.php      2006-11-17 
12:57:12 UTC (rev 3957)
+++ trunk/Base/tests/extra_repository/Translation/test.php      2006-11-17 
13:06:33 UTC (rev 3958)
@@ -0,0 +1,8 @@
+<?php
+
+class extTranslationTest
+{
+
+}
+
+?>


Property changes on: trunk/Base/tests/extra_repository/Translation/test.php
___________________________________________________________________
Name: svn:eol-style
   + native

Added: trunk/Base/tests/extra_repository/autoload/translation_autoload.php
===================================================================
--- trunk/Base/tests/extra_repository/autoload/translation_autoload.php 
2006-11-17 12:57:12 UTC (rev 3957)
+++ trunk/Base/tests/extra_repository/autoload/translation_autoload.php 
2006-11-17 13:06:33 UTC (rev 3958)
@@ -0,0 +1,7 @@
+<?php
+
+return array(
+    'extTranslationTest' => 'Translation/test.php',
+);
+
+?>


Property changes on: 
trunk/Base/tests/extra_repository/autoload/translation_autoload.php
___________________________________________________________________
Name: svn:eol-style
   + native

Added: trunk/Base/tests/test_repository/TestClasses/base_test_long_class.php
===================================================================
--- trunk/Base/tests/test_repository/TestClasses/base_test_long_class.php       
2006-11-17 12:57:12 UTC (rev 3957)
+++ trunk/Base/tests/test_repository/TestClasses/base_test_long_class.php       
2006-11-17 13:06:33 UTC (rev 3958)
@@ -0,0 +1,6 @@
+<?php
+ezcTestRunner::addFileToFilter( __FILE__ );
+
+class trBasetestLongClass {
+}
+?>


Property changes on: 
trunk/Base/tests/test_repository/TestClasses/base_test_long_class.php
___________________________________________________________________
Name: svn:eol-style
   + native

Modified: trunk/Base/tests/test_repository/autoload_files/basetest_autoload.php
===================================================================
--- trunk/Base/tests/test_repository/autoload_files/basetest_autoload.php       
2006-11-17 12:57:12 UTC (rev 3957)
+++ trunk/Base/tests/test_repository/autoload_files/basetest_autoload.php       
2006-11-17 13:06:33 UTC (rev 3958)
@@ -3,6 +3,7 @@
 
 return array(
        'trBasetestClass' => 'TestClasses/base_test_class.php',
-       'trBasetestClass2' => 'TestClasses/base_test_class_number_two.php'
+       'trBasetestClass2' => 'TestClasses/base_test_class_number_two.php',
+       'trBasetestClass4' => 'TestClasses/base_test_class_number_four.php',
 );
 ?>

Added: 
trunk/Base/tests/test_repository/autoload_files/basetest_long_autoload.php
===================================================================
--- trunk/Base/tests/test_repository/autoload_files/basetest_long_autoload.php  
2006-11-17 12:57:12 UTC (rev 3957)
+++ trunk/Base/tests/test_repository/autoload_files/basetest_long_autoload.php  
2006-11-17 13:06:33 UTC (rev 3958)
@@ -0,0 +1,7 @@
+<?php
+ezcTestRunner::addFileToFilter( __FILE__ );
+
+return array(
+       'trBasetestLongClass' => 'TestClasses/base_test_long_class.php',
+);
+?>


Property changes on: 
trunk/Base/tests/test_repository/autoload_files/basetest_long_autoload.php
___________________________________________________________________
Name: svn:eol-style
   + native

-- 
svn-components mailing list
svn-components@lists.ez.no
http://lists.ez.no/mailman/listinfo/svn-components

Reply via email to