ClassUtils.class.php

Go to the documentation of this file.
00001 <?php
00002 /***************************************************************************
00003  *   Copyright (C) 2007-2009 by Dmitry E. Demidov                          *
00004  *                                                                         *
00005  *   This program is free software; you can redistribute it and/or modify  *
00006  *   it under the terms of the GNU Lesser General Public License as        *
00007  *   published by the Free Software Foundation; either version 3 of the    *
00008  *   License, or (at your option) any later version.                       *
00009  *                                                                         *
00010  ***************************************************************************/
00011 
00015     final class ClassUtils extends StaticFactory
00016     {
00017         const CLASS_NAME_PATTERN = '[a-zA-Z_\x7f-\xff][a-zA-Z0-9_\x7f-\xff]*';
00018         
00019         /* void */ public static function copyProperties($source, $destination)
00020         {
00021             Assert::isEqual(get_class($source), get_class($destination));
00022             
00023             $class = new ReflectionClass($source);
00024             
00025             foreach ($class->getProperties() as $property) {
00026                 $name = ucfirst($property->getName());
00027                 $getter = 'get'.$name;
00028                 $setter = 'set'.$name;
00029                 
00030                 if (
00031                     ($class->hasMethod($getter))
00032                     && ($class->hasMethod($setter))
00033                 ) {
00034                     
00035                     $sourceValue = $source->$getter();
00036                     
00037                     if ($sourceValue === null) {
00038                         
00039                         $setMethood = $class->getMethod($setter);
00040                         $parameterList = $setMethood->getParameters();
00041                         $firstParameter = $parameterList[0];
00042                         
00043                         if ($firstParameter->allowsNull())
00044                             $destination->$setter($sourceValue);
00045                         
00046                     } else {
00047                         $destination->$setter($sourceValue);
00048                     }
00049                 }
00050             }
00051         }
00052         
00053         /* void */ public static function copyNotNullProperties($source, $destination)
00054         {
00055             Assert::isTrue(get_class($source) == get_class($destination));
00056             
00057             $class = new ReflectionClass($source);
00058             
00059             foreach ($class->getProperties() as $property) {
00060                 $name = ucfirst($property->getName());
00061                 $getter = 'get'.$name;
00062                 $setter = 'set'.$name;
00063                 
00064                 if (
00065                     ($class->hasMethod($getter))
00066                     && ($class->hasMethod($setter))
00067                 ) {
00068                     $value = $source->$getter();
00069                     if ($value !== null)
00070                         $destination->$setter($value);
00071                 }
00072             }
00073         }
00074         
00075         /* void */ public static function fillNullProperties($source, $destination)
00076         {
00077             Assert::isTrue(get_class($source) == get_class($destination));
00078             
00079             $class = new ReflectionClass($source);
00080             
00081             foreach ($class->getProperties() as $property) {
00082                 $name = ucfirst($property->getName());
00083                 $getter = 'get'.$name;
00084                 $setter = 'set'.$name;
00085                 
00086                 if (
00087                     ($class->hasMethod($getter))
00088                     && ($class->hasMethod($setter))
00089                 ) {
00090                     $destinationValue = $destination->$getter();
00091                     $sourceValue = $source->$getter();
00092                     
00093                     if (
00094                         ($destinationValue === null)
00095                         && ($sourceValue !== null)
00096                     ) {
00097                         $destination->$setter($sourceValue);
00098                     }
00099                 }
00100             }
00101         }
00102         
00103         public static function isClassName($className)
00104         {
00105             if (!is_string($className))
00106                 return false;
00107 
00108             return preg_match('/^'.self::CLASS_NAME_PATTERN.'$/', $className) > 0;
00109         }
00110         
00112         public static function isClassImplements($what)
00113         {
00114             static $classImplements = null;
00115             
00116             if (!$classImplements) {
00117                 if (!function_exists('class_implements')) {
00118                     $classImplements = create_function(
00119                         '$what',
00120                         '
00121                             $info = new ReflectionClass($what);
00122                             return $info->getInterfaceNames();
00123                         '
00124                     );
00125                 } else {
00126                     $classImplements = 'class_implements';
00127                 }
00128             }
00129             
00130             return $classImplements($what, true);
00131         }
00132         
00133         public static function isInstanceOf($object, $class)
00134         {
00135             if (is_object($class)) {
00136                 $className = get_class($class);
00137             } elseif (is_string($class)) {
00138                 $className = $class;
00139             } else {
00140                 throw new WrongArgumentException('strange class given');
00141             }
00142             
00143             if (
00144                 is_string($object)
00145                 && self::isClassName($object)
00146             ) {
00147                 if ($object == $className)
00148                     return true;
00149                 elseif (is_subclass_of($object, $className))
00150                     return true;
00151                 else
00152                     return in_array(
00153                         $class,
00154                         self::isClassImplements($object)
00155                     );
00156             } elseif (is_object($object)) {
00157                 return $object instanceof $className;
00158                 
00159             } else {
00160                 throw new WrongArgumentException('strange object given');
00161             }
00162         }
00163         
00164         public static function callStaticMethod($methodSignature /* , ... */)
00165         {
00166             $agruments = func_get_args();
00167             array_shift($agruments);
00168             
00169             return
00170                 call_user_func_array(
00171                     self::checkStaticMethod($methodSignature),
00172                     $agruments
00173                 );
00174         }
00175         
00176         public static function checkStaticMethod($methodSignature)
00177         {
00178             $nameParts = explode('::', $methodSignature, 2);
00179             
00180             if (count($nameParts) != 2)
00181                 throw new WrongArgumentException('incorrect method signature');
00182             
00183             list($className, $methodName) = $nameParts;
00184             
00185             try {
00186                 $class = new ReflectionClass($className);
00187             } catch (ReflectionException $e) {
00188                 throw new ClassNotFoundException($className);
00189             }
00190             
00191             Assert::isTrue(
00192                 $class->hasMethod($methodName),
00193                 "knows nothing about '{$className}::{$methodName}' method"
00194             );
00195             
00196             $method = $class->getMethod($methodName);
00197             
00198             Assert::isTrue(
00199                 $method->isStatic(),
00200                 "method is not static '{$className}::{$methodName}'"
00201             );
00202             
00203             Assert::isTrue(
00204                 $method->isPublic(),
00205                 "method is not public '{$className}::{$methodName}'"
00206             );
00207             
00208             return $nameParts;
00209         }
00210         
00211         /* void */ public static function preloadAllClasses()
00212         {
00213             foreach (explode(PATH_SEPARATOR, get_include_path()) as $directory) {
00214                 foreach (
00215                     glob(
00216                         $directory.DIRECTORY_SEPARATOR.'/*'.EXT_CLASS,
00217                         GLOB_NOSORT
00218                     )
00219                     as $file
00220                 ) {
00221                     $className = basename($file, EXT_CLASS);
00222                     
00223                     if (
00224                         !class_exists($className)
00225                         && !interface_exists($className)
00226                     ) {
00227                         include $file;
00228                     }
00229                 }
00230             }
00231         }
00232     }
00233 ?>