00001 <?php
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00016 final class ClassUtils extends StaticFactory
00017 {
00018 const CLASS_NAME_PATTERN = '[a-zA-Z_\x7f-\xff][a-zA-Z0-9_\x7f-\xff]*';
00019
00020 public static function copyProperties($source, $destination)
00021 {
00022 Assert::isTrue(get_class($source) == get_class($destination));
00023
00024 $class = new ReflectionClass($source);
00025
00026 foreach ($class->getProperties() as $property) {
00027 $name = ucfirst($property->getName());
00028 $getter = 'get'.$name;
00029 $setter = 'set'.$name;
00030
00031 if (
00032 ($class->hasMethod($getter))
00033 && ($class->hasMethod($setter))
00034 ) {
00035
00036 $sourceValue = $source->$getter();
00037
00038 if ($sourceValue === null) {
00039
00040 $setMethood = $class->getMethod($setter);
00041 $parameterList = $setMethood->getParameters();
00042 $firstParameter = $parameterList[0];
00043
00044 if ($firstParameter->allowsNull())
00045 $destination->$setter($sourceValue);
00046
00047 } else {
00048 $destination->$setter($sourceValue);
00049 }
00050 }
00051 }
00052 }
00053
00054 public static function copyNotNullProperties($source, $destination)
00055 {
00056 Assert::isTrue(get_class($source) == get_class($destination));
00057
00058 $class = new ReflectionClass($source);
00059
00060 foreach ($class->getProperties() as $property) {
00061 $name = ucfirst($property->getName());
00062 $getter = 'get'.$name;
00063 $setter = 'set'.$name;
00064
00065 if (
00066 ($class->hasMethod($getter))
00067 && ($class->hasMethod($setter))
00068 ) {
00069 $value = $source->$getter();
00070 if ($value !== null)
00071 $destination->$setter($value);
00072 }
00073 }
00074 }
00075
00076 public static function fillNullProperties($source, $destination)
00077 {
00078 Assert::isTrue(get_class($source) == get_class($destination));
00079
00080 $class = new ReflectionClass($source);
00081
00082 foreach ($class->getProperties() as $property) {
00083 $name = ucfirst($property->getName());
00084 $getter = 'get'.$name;
00085 $setter = 'set'.$name;
00086
00087 if (
00088 ($class->hasMethod($getter))
00089 && ($class->hasMethod($setter))
00090 ) {
00091 $destinationValue = $destination->$getter();
00092 $sourceValue = $source->$getter();
00093
00094 if (
00095 ($destinationValue === null)
00096 && ($sourceValue !== null)
00097 ) {
00098 $destination->$setter($sourceValue);
00099 }
00100 }
00101 }
00102 }
00103
00104 public static function isClassName($className)
00105 {
00106 return preg_match('/^'.self::CLASS_NAME_PATTERN.'$/', $className);
00107 }
00108
00109 public static function isInstanceOf($object, $class)
00110 {
00111 if (is_object($class)) {
00112 $className = get_class($class);
00113 } elseif (is_string($class)) {
00114 $className = $class;
00115 } else {
00116 throw new WrongArgumentException('strange class given');
00117 }
00118
00119 if (
00120 is_string($object)
00121 && self::isClassName($object)
00122 ) {
00123 if ($object == $className)
00124 return true;
00125 elseif (is_subclass_of($object, $className))
00126 return true;
00127 else
00128 return in_array(
00129 $class,
00130 class_implements($object, true)
00131 );
00132
00133 } elseif (is_object($object)) {
00134 return $object instanceof $className;
00135
00136 } else {
00137 throw new WrongArgumentException('strange object given');
00138 }
00139 }
00140
00141 public static function callStaticMethod($methodSignature )
00142 {
00143 $agruments = func_get_args();
00144 array_shift($agruments);
00145
00146 return
00147 call_user_func_array(
00148 self::checkStaticMethod($methodSignature),
00149 $agruments
00150 );
00151 }
00152
00153 public static function checkStaticMethod($methodSignature)
00154 {
00155 $nameParts = explode('::', $methodSignature, 2);
00156
00157 if (count($nameParts) != 2)
00158 throw new WrongArgumentException('incorrect method signature');
00159
00160 list($className, $methodName) = $nameParts;
00161
00162 try {
00163 $class = new ReflectionClass($className);
00164 } catch (ReflectionException $e) {
00165 throw new ClassNotFoundException($className);
00166 }
00167
00168 Assert::isTrue(
00169 $class->hasMethod($methodName),
00170 "knows nothing about '{$className}::{$methodName}' method"
00171 );
00172
00173 $method = $class->getMethod($methodName);
00174
00175 Assert::isTrue(
00176 $method->isStatic(),
00177 "method is not static '{$className}::{$methodName}'"
00178 );
00179
00180 Assert::isTrue(
00181 $method->isPublic(),
00182 "method is not public '{$className}::{$methodName}'"
00183 );
00184
00185 return $nameParts;
00186 }
00187
00188 public static function dtoObject2xml(
00189 $object,
00190 $classMap,
00191 $xmlDoc = null,
00192 $ignoreNull = false
00193 )
00194 {
00195 Assert::isTrue(is_object($object));
00196
00197 $class = new ReflectionClass($object);
00198
00199 if (array_key_exists($class->getName(), $classMap))
00200 $className = $classMap[$class->getName()];
00201 else
00202 $className = $class->getName();
00203
00204 $root = new DomElement($className);
00205
00206 if ($xmlDoc)
00207 $xmlDoc->appendChild($root);
00208
00209 $propertyList = $class->getProperties();
00210
00211 foreach ($propertyList as $property) {
00212
00213 $name = $property->getName();
00214
00215 $getter = 'get'.ucfirst($name);
00216
00217 if ($class->hasMethod($getter)) {
00218 $value = $object->$getter();
00219 if (!$ignoreNull) {
00220 if (is_array($value)) {
00221 $element = new DomElement($name);
00222
00223 $root->appendChild($element);
00224
00225 foreach ($value as $innerObject) {
00226 ClassUtils::dtoObject2xml(
00227 $innerObject,
00228 $classMap,
00229 $element
00230 );
00231 }
00232 } elseif (is_object($value)) {
00233 if ($value instanceof Timestamp) {
00234 $element =
00235 new DomElement(
00236 $name,
00237 $value->toISOString()
00238 );
00239
00240 $root->appendChild($element);
00241 } else {
00242 throw new WrongArgumentException(
00243 'I dont know how to convert object of '
00244 . get_class($value) . ' class to xml.'
00245 );
00246 }
00247 } else {
00248 $element = new DomElement($name, $value);
00249
00250 $root->appendChild($element);
00251 }
00252 }
00253 }
00254 }
00255 }
00256
00257 public static function xml2dtoObject(
00258 &$object,
00259 $classMap,
00260 $simpleXml,
00261 $ignoreNull = false
00262 )
00263 {
00264 $className = $simpleXml->getName();
00265
00266 if (array_key_exists($className, $classMap))
00267 $className = $classMap[$className];
00268
00269 if (!$object)
00270 $object = new $className;
00271
00272 $class = new ReflectionClass($object);
00273
00274 $propertyList = $class->getProperties();
00275
00276 foreach ($propertyList as $property) {
00277
00278 $name = $property->getName();
00279
00280 $setter = 'set'.ucfirst($name);
00281
00282 if ($class->hasMethod($setter)) {
00283 if (!$ignoreNull) {
00284 if ($children = $simpleXml->$name->children()) {
00285 $innerObjects = array();
00286
00287 foreach ($children as $child) {
00288 ClassUtils::xml2dtoObject(
00289 $innerObject,
00290 $classMap,
00291 $child
00292 );
00293
00294 $innerObjects[] = $innerObject;
00295 unset($innerObject);
00296 }
00297
00298 $object->$setter($innerObjects);
00299 } else {
00300 $object->$setter((string) $simpleXml->$name);
00301 }
00302 }
00303 }
00304 }
00305 }
00306 }
00307 ?>