Show
Ignore:
Timestamp:
11/22/07 13:40:22 (14 months ago)
Author:
wernerm
Message:

Added isValidModelClass() static method and fixed getLoadedModels() in order to resort back to the (classical) approach of class inclusion as a fallback when record classes have different names than their file names. The fallback behaviour of getLoadedModels() is now similar to what is was before the changes introduced in rev 3002.

Files:
1 modified

Legend:

Unmodified
Added
Removed
  • trunk/lib/Doctrine.php

    r3155 r3204  
    3838     */ 
    3939    const VERSION                   = '0.1.0'; 
    40      
     40 
    4141    /** 
    4242     * ERROR CONSTANTS 
     
    362362     */ 
    363363    const HYDRATE_ARRAY             = 3; 
    364      
     364 
    365365    /** 
    366366     * HYDRATE_NONE 
     
    436436     */ 
    437437    private static $_debug = false; 
    438      
     438 
    439439    /** 
    440440     * _loadedModels 
    441      *  
     441     * 
    442442     * Array of all the loaded models and the path to each one for autoloading 
    443443     * 
     
    445445     */ 
    446446    private static $_loadedModels = array(); 
    447      
     447 
    448448    /** 
    449449     * _validators 
     
    468468     * debug 
    469469     * 
    470      * @param string $bool  
     470     * @param string $bool 
    471471     * @return void 
    472472     */ 
     
    476476            self::$_debug = (bool) $bool; 
    477477        } 
    478          
     478 
    479479        return self::$_debug; 
    480480    } 
     
    491491            self::$_path = dirname(__FILE__); 
    492492        } 
    493          
     493 
    494494        return self::$_path; 
    495495    } 
     
    499499     * 
    500500     * Recursively load all models from a directory or array of directories 
    501      *  
    502      * @param string $directory Path to directory of models or array of directory paths 
     501     * 
     502     * @param string $directory    Path to directory of models or array of directory paths 
    503503     * @return array $loadedModels 
    504504     */ 
     
    507507        if ($directory !== null) { 
    508508            $manager = Doctrine_Manager::getInstance(); 
    509              
     509 
    510510            foreach ((array) $directory as $dir) { 
    511511                $it = new RecursiveIteratorIterator(new RecursiveDirectoryIterator($dir), 
    512512                                                        RecursiveIteratorIterator::LEAVES_ONLY); 
    513  
    514513                foreach ($it as $file) { 
    515514                    $e = explode('.', $file->getFileName()); 
     
    528527     * 
    529528     * Get all the loaded models, you can provide an array of classes or it will use get_declared_classes() 
    530      *  
     529     * 
    531530     * Will filter through an array of classes and return the Doctrine_Records out of them. 
    532531     * If you do not specify $classes it will return all of the currently loaded Doctrine_Records 
    533532     * 
    534      * @param $classes Array of classes to filter through, otherwise uses get_declared_classes() 
    535      * @return array $loadedModels 
     533     * @param classes Array of classes to filter through, otherwise uses get_declared_classes() 
     534     * @return array   $loadedModels 
    536535     */ 
    537536    public static function getLoadedModels($classes = null) 
     
    541540            $classes = array_merge($classes, array_keys(self::$_loadedModels)); 
    542541        } 
    543          
    544         $parent = new ReflectionClass('Doctrine_Record'); 
    545          
     542 
    546543        $loadedModels = array(); 
    547          
     544 
    548545        foreach ((array) $classes as $name) { 
    549             $class = new ReflectionClass($name); 
    550              
     546 
     547            try { 
     548                $class = new ReflectionClass($name); 
     549                if (self::isValidModelClass($class)) { 
     550                    $loadedModels[] = $name; 
     551                } 
     552            } catch (Exception $e) { 
     553                // Determine class names by the actual inclusion of the model file 
     554                // The possibility exists that the class name(s) contained in the model 
     555                // file is not the same as the actual model file name itself 
     556                if (isset(self::$_loadedModels[$name])) { 
     557                    $declaredBefore = get_declared_classes(); 
     558                    try { 
     559                        require_once self::$_loadedModels[$name]; 
     560                        $declaredAfter = get_declared_classes(); 
     561                        // Using array_slice since array_diff is broken is some versions 
     562                        $foundClasses = array_slice($declaredAfter, count($declaredBefore)-1); 
     563                        if ($foundClasses) { 
     564                            foreach ($foundClasses as $name) { 
     565                                $class = new ReflectionClass($name); 
     566                                if (self::isValidModelClass($class)) { 
     567                                    $loadedModels[] = $name; 
     568                                } 
     569                            } 
     570                        } 
     571                    } catch (Exception $e) { 
     572                        continue; 
     573                    } 
     574                } 
     575            } 
     576 
     577        } 
     578 
     579        return $loadedModels; 
     580    } 
     581 
     582 
     583    /** 
     584     * isValidModelClass 
     585     * 
     586     * Checks whether a reflection class is a valid Doctrine model class 
     587     * 
     588     * @param class  A reflection class to validate 
     589     * @return boolean 
     590     */ 
     591    public static function isValidModelClass($class) 
     592    { 
     593        if ($class instanceof ReflectionClass) { 
    551594            // Skip the following classes 
    552595            // - abstract classes 
    553             // - not a subclass of Doctrine_Record  
     596            // - not a subclass of Doctrine_Record 
    554597            // - don't have a setTableDefinition method 
    555             if ($class->isAbstract() ||  
    556                 !$class->isSubClassOf($parent) ||  
    557                 !$class->hasMethod('setTableDefinition')) { 
    558                 continue; 
     598            if (!$class->isAbstract() && 
     599                $class->isSubClassOf('Doctrine_Record') && 
     600                $class->hasMethod('setTableDefinition')) { 
     601                return true; 
    559602            } 
    560              
    561             $loadedModels[] = $name; 
    562         } 
    563          
    564         return $loadedModels; 
    565     } 
     603        } 
     604        return false; 
     605    } 
     606 
    566607 
    567608    /** 
     
    569610     * 
    570611     * Get the connection object for a table by the actual table name 
    571      *  
    572      * @param string $tableName  
     612     * 
     613     * @param string $tableName 
    573614     * @return object Doctrine_Connection 
    574615     */ 
     
    576617    { 
    577618        $loadedModels = self::getLoadedModels(); 
    578          
     619 
    579620        foreach ($loadedModels as $name) { 
    580621            $model = new $name(); 
    581622            $table = $model->getTable(); 
    582              
     623 
    583624            if ($table->getTableName() == $tableName) { 
    584                return $table->getConnection();  
     625               return $table->getConnection(); 
    585626            } 
    586627        } 
    587          
     628 
    588629        return Doctrine_Manager::connection(); 
    589630    } 
     
    620661 
    621662        $export = new Doctrine_Export_Schema(); 
    622          
     663 
    623664        $result = $export->exportSchema($yamlPath, 'yml', $directory); 
    624          
     665 
    625666        exec('rm -rf ' . $directory); 
    626          
     667 
    627668        return $result; 
    628669    } 
     
    642683        $import = new Doctrine_Import_Schema(); 
    643684        $import->setOptions($options); 
    644          
     685 
    645686        return $import->importSchema($yamlPath, 'yml', $directory); 
    646687    } 
     
    675716     * generateSqlFromModels 
    676717     * 
    677      * @param string $directory  
     718     * @param string $directory 
    678719     * @return string $build  String of sql queries. One query per line 
    679720     */ 
     
    681722    { 
    682723        $sql = Doctrine_Manager::connection()->export->exportSql($directory); 
    683          
     724 
    684725        $build = ''; 
    685726        foreach ($sql as $query) { 
    686727            $build .= $query.";\n"; 
    687728        } 
    688          
     729 
    689730        return $build; 
    690731    } 
     
    702743    { 
    703744        $export = new Doctrine_Export_Schema(); 
    704          
     745 
    705746        return $export->exportSchema($yamlPath, 'yml', $directory); 
    706747    } 
     
    719760            $specifiedConnections = (array) $specifiedConnections; 
    720761        } 
    721          
     762 
    722763        $manager = Doctrine_Manager::getInstance(); 
    723764        $connections = $manager->getConnections(); 
    724          
     765 
    725766        $results = array(); 
    726          
     767 
    727768        foreach ($connections as $name => $connection) { 
    728769            if ( ! empty($specifiedConnections) && !in_array($name, $specifiedConnections)) { 
    729770                continue; 
    730771            } 
    731              
     772 
    732773            $info = $manager->parsePdoDsn($connection->getOption('dsn')); 
    733774            $username = $connection->getOption('username'); 
    734775            $password = $connection->getOption('password'); 
    735              
     776 
    736777            // Make connection without database specified so we can create it 
    737778            $connect = $manager->openConnection(new PDO($info['scheme'] . ':host=' . $info['host'], $username, $password), 'tmp_connection', false); 
    738              
     779 
    739780            try { 
    740781                // Create database 
    741782                $connect->export->createDatabase($name); 
    742                  
     783 
    743784                // Close the tmp connection with no database 
    744785                $manager->closeConnection($connect); 
    745                  
     786 
    746787                // Close original connection 
    747788                $manager->closeConnection($connection); 
    748                  
     789 
    749790                // Reopen original connection with newly created database 
    750791                $manager->openConnection(new PDO($info['dsn'], $username, $password), $name, true); 
    751                  
     792 
    752793                $results[$name] = true; 
    753794            } catch (Exception $e) { 
     
    755796            } 
    756797        } 
    757          
     798 
    758799        return $results; 
    759800    } 
     
    772813            $specifiedConnections = (array) $specifiedConnections; 
    773814        } 
    774          
     815 
    775816        $manager = Doctrine_Manager::getInstance(); 
    776          
     817 
    777818        $connections = $manager->getConnections(); 
    778          
     819 
    779820        $results = array(); 
    780          
     821 
    781822        foreach ($connections as $name => $connection) { 
    782823            if ( ! empty($specifiedConnections) && !in_array($name, $specifiedConnections)) { 
    783824                continue; 
    784825            } 
    785              
     826 
    786827            try { 
    787828                $connection->export->dropDatabase($name); 
    788                  
     829 
    789830                $results[$name] = true; 
    790831            } catch (Exception $e) { 
     
    792833            } 
    793834        } 
    794          
     835 
    795836        return $results; 
    796837    } 
     
    808849    { 
    809850        $data = new Doctrine_Data(); 
    810          
     851 
    811852        return $data->exportData($yamlPath, 'yml', array(), $individualFiles); 
    812853    } 
     
    825866    { 
    826867        $data = new Doctrine_Data(); 
    827          
     868 
    828869        if ( ! $append) { 
    829870            $data->purge(); 
    830871        } 
    831          
     872 
    832873        return $data->importData($yamlPath, 'yml'); 
    833874    } 
     
    835876    /** 
    836877     * migrate 
    837      *  
     878     * 
    838879     * Migrate database to specified $to version. Migrates from current to latest if you do not specify. 
    839880     * 
     
    846887    { 
    847888        $migration = new Doctrine_Migration($migrationsPath); 
    848          
     889 
    849890        return $migration->migrate($to); 
    850891    } 
     
    861902    { 
    862903        $builder = new Doctrine_Migration_Builder($migrationsPath); 
    863          
     904 
    864905        return $builder->generateMigrationClass($className); 
    865906    } 
     
    868909     * generateMigrationsFromDb 
    869910     * 
    870      * @param string $migrationsPath  
     911     * @param string $migrationsPath 
    871912     * @return void 
    872913     * @throws new Doctrine_Migration_Exception 
     
    875916    { 
    876917        $builder = new Doctrine_Migration_Builder($migrationsPath); 
    877          
     918 
    878919        return $builder->generateMigrationsFromDb(); 
    879920    } 
     
    882923     * generateMigrationsFromModels 
    883924     * 
    884      * @param string $migrationsPath  
    885      * @param string $modelsPath  
     925     * @param string $migrationsPath 
     926     * @param string $modelsPath 
    886927     * @return void 
    887928     */ 
     
    889930    { 
    890931        $builder = new Doctrine_Migration_Builder($migrationsPath); 
    891          
     932 
    892933        return $builder->generateMigrationsFromModels($modelsPath); 
    893934    } 
     
    896937     * getTable 
    897938     * 
    898      * @param string $tableName  
     939     * @param string $tableName 
    899940     * @return void 
    900941     */ 
     
    907948     * fileFinder 
    908949     * 
    909      * @param string $type  
     950     * @param string $type 
    910951     * @return void 
    911952     */ 
     
    946987            return false; 
    947988        } 
    948          
     989 
    949990        if ( ! self::$_path) { 
    950991            self::$_path = dirname(__FILE__); 
    951992        } 
    952          
     993 
    953994        $class = self::$_path . DIRECTORY_SEPARATOR . str_replace('_', DIRECTORY_SEPARATOR, $className) . '.php'; 
    954995 
    955996        if (file_exists($class)) { 
    956997            require_once($class); 
    957              
     998 
    958999            return true; 
    9591000        } 
    960          
     1001 
    9611002        $loadedModels = self::$_loadedModels; 
    962          
     1003 
    9631004        if (isset($loadedModels[$className]) && file_exists($loadedModels[$className])) { 
    9641005            require_once($loadedModels[$className]); 
    965              
     1006 
    9661007            return true; 
    9671008        } 
     
    9881029                $indent .= "    "; 
    9891030                foreach ($var as $k => $v) { 
    990                      
     1031 
    9911032                    $ret[] = $indent . $k . ' : ' . self::dump($v, false, $indent); 
    9921033                } 
     
    10351076     * classifyCallback 
    10361077     * 
    1037      * Callback function to classify a classname properly.  
     1078     * Callback function to classify a classname properly. 
    10381079     * 
    10391080     * @param array $matches An array of matches from a pcre_replace call 
    1040      * @return string A string with matches 1 and mathces 3 in upper case.  
     1081     * @return string A string with matches 1 and mathces 3 in upper case. 
    10411082     */ 
    10421083    public static function classifyCallback($matches) 
     
    10611102        return true; 
    10621103    } 
    1063      
     1104 
    10641105    /** 
    10651106     * makeDirectories 
    1066      *  
     1107     * 
    10671108     * Makes the directories for a path recursively 
    10681109     * 
    1069      * @param string $path  
     1110     * @param string $path 
    10701111     * @return void 
    10711112     */ 
     
    10751116          return false; 
    10761117        } 
    1077          
     1118 
    10781119        if (is_dir($path) || is_file($path)) { 
    10791120          return true; 
    10801121        } 
    10811122 
    1082         return mkdir($path, $mode, true);  
    1083     } 
    1084      
     1123        return mkdir($path, $mode, true); 
     1124    } 
     1125 
    10851126    /** 
    10861127     * removeDirectories 
    10871128     * 
    1088      * @param string $folderPath  
     1129     * @param string $folderPath 
    10891130     * @return void 
    10901131     */ 
     
    11121153        } 
    11131154    } 
    1114      
     1155 
    11151156    /** 
    11161157     * getValidators 
     
    11241165        if (empty(self::$_validators)) { 
    11251166            $dir = Doctrine::getPath() . DIRECTORY_SEPARATOR . 'Doctrine' . DIRECTORY_SEPARATOR . 'Validator'; 
    1126          
     1167 
    11271168            $files = new RecursiveIteratorIterator(new RecursiveDirectoryIterator($dir), RecursiveIteratorIterator::LEAVES_ONLY); 
    11281169            foreach ($files as $file) { 
    11291170                $e = explode('.', $file->getFileName()); 
    1130                  
     1171 
    11311172                if (end($e) == 'php') { 
    11321173                    $name = strtolower($e[0]); 
    1133                      
     1174 
    11341175                    self::$_validators[$name] = $name; 
    11351176                } 
    11361177            } 
    11371178        } 
    1138          
     1179 
    11391180        return self::$_validators; 
    11401181    }