PageRenderTime 26ms CodeModel.GetById 20ms RepoModel.GetById 0ms app.codeStats 0ms

/library/Zend/CodeGenerator/Php/PhpClass.php

https://github.com/adaykin/zf2
PHP | 562 lines | 424 code | 32 blank | 106 comment | 12 complexity | 44a343e50ee651827aa80c188569b943 MD5 | raw file
  1. <?php
  2. /**
  3. * Zend Framework
  4. *
  5. * LICENSE
  6. *
  7. * This source file is subject to the new BSD license that is bundled
  8. * with this package in the file LICENSE.txt.
  9. * It is also available through the world-wide-web at this URL:
  10. * http://framework.zend.com/license/new-bsd
  11. * If you did not receive a copy of the license and are unable to
  12. * obtain it through the world-wide-web, please send an email
  13. * to license@zend.com so we can send you a copy immediately.
  14. *
  15. * @category Zend
  16. * @package Zend_CodeGenerator
  17. * @subpackage PHP
  18. * @copyright Copyright (c) 2005-2011 Zend Technologies USA Inc. (http://www.zend.com)
  19. * @license http://framework.zend.com/license/new-bsd New BSD License
  20. */
  21. /**
  22. * @namespace
  23. */
  24. namespace Zend\CodeGenerator\Php;
  25. /**
  26. * @uses \Zend\CodeGenerator\Php\AbstractPhp
  27. * @uses \Zend\CodeGenerator\PhpDocblock
  28. * @uses \Zend\CodeGenerator\Php\Exception
  29. * @uses \Zend\CodeGenerator\Php\PhpMember\MemberContainer
  30. * @uses \Zend\CodeGenerator\Php\PhpMethod
  31. * @uses \Zend\CodeGenerator\Php\PhpProperty
  32. * @category Zend
  33. * @package Zend_CodeGenerator
  34. * @copyright Copyright (c) 2005-2011 Zend Technologies USA Inc. (http://www.zend.com)
  35. * @license http://framework.zend.com/license/new-bsd New BSD License
  36. */
  37. class PhpClass extends AbstractPhp
  38. {
  39. /**
  40. * @var \Zend\CodeGenerator\Php\PhpFile
  41. */
  42. protected $_phpFile = null;
  43. /**
  44. * @var string
  45. */
  46. protected $_namespaceName = null;
  47. /**
  48. * @var \Zend\CodeGenerator\Php\PhpDocblock
  49. */
  50. protected $_docblock = null;
  51. /**
  52. * @var string
  53. */
  54. protected $_name = null;
  55. /**
  56. * @var bool
  57. */
  58. protected $_isAbstract = false;
  59. /**
  60. * @var string
  61. */
  62. protected $_extendedClass = null;
  63. /**
  64. * @var array Array of string names
  65. */
  66. protected $_implementedInterfaces = array();
  67. /**
  68. * @var array Array of properties
  69. */
  70. protected $_properties = null;
  71. /**
  72. * @var array Array of methods
  73. */
  74. protected $_methods = null;
  75. /**
  76. * fromReflection() - build a Code Generation Php Object from a Class Reflection
  77. *
  78. * @param \Zend\Reflection\ReflectionClass $reflectionClass
  79. * @return \Zend\CodeGenerator\Php\PhpClass
  80. */
  81. public static function fromReflection(\Zend\Reflection\ReflectionClass $reflectionClass)
  82. {
  83. $class = new self();
  84. $class->setSourceContent($class->getSourceContent());
  85. $class->setSourceDirty(false);
  86. if ($reflectionClass->getDocComment() != '') {
  87. $class->setDocblock(PhpDocblock::fromReflection($reflectionClass->getDocblock()));
  88. }
  89. $class->setAbstract($reflectionClass->isAbstract());
  90. // set the namespace
  91. if ($reflectionClass->inNamespace()) {
  92. $class->setNamespaceName($reflectionClass->getNamespaceName());
  93. }
  94. $class->setName($reflectionClass->getName());
  95. if ($parentClass = $reflectionClass->getParentClass()) {
  96. $class->setExtendedClass($parentClass->getName());
  97. $interfaces = array_diff($reflectionClass->getInterfaces(), $parentClass->getInterfaces());
  98. } else {
  99. $interfaces = $reflectionClass->getInterfaces();
  100. }
  101. $interfaceNames = array();
  102. foreach($interfaces AS $interface) {
  103. $interfaceNames[] = $interface->getName();
  104. }
  105. $class->setImplementedInterfaces($interfaceNames);
  106. $properties = array();
  107. foreach ($reflectionClass->getProperties() as $reflectionProperty) {
  108. if ($reflectionProperty->getDeclaringClass()->getName() == $class->getName()) {
  109. $properties[] = PhpProperty::fromReflection($reflectionProperty);
  110. }
  111. }
  112. $class->setProperties($properties);
  113. $methods = array();
  114. foreach ($reflectionClass->getMethods() as $reflectionMethod) {
  115. if ($reflectionMethod->getDeclaringClass()->getName() == $class->getName()) {
  116. $methods[] = PhpMethod::fromReflection($reflectionMethod);
  117. }
  118. }
  119. $class->setMethods($methods);
  120. return $class;
  121. }
  122. /**
  123. * setPhpFile()
  124. *
  125. * @param Zend\CodeGenerator\Php\PhpFile $phpFile
  126. */
  127. public function setPhpFile(PhpFile $phpFile)
  128. {
  129. $this->_phpFile = $phpFile;
  130. return $this;
  131. }
  132. /**
  133. * getPhpFile()
  134. *
  135. * @return Zend\CodeGenerator\Php\PhpFile
  136. */
  137. public function getPhpFile()
  138. {
  139. return $this->_phpFile;
  140. }
  141. /**
  142. * setDocblock() Set the docblock
  143. *
  144. * @param \Zend\CodeGenerator\PhpDocblock|array|string $docblock
  145. * @return \Zend\CodeGenerator\Php\PhpFile
  146. */
  147. public function setDocblock($docblock)
  148. {
  149. if (is_string($docblock)) {
  150. $docblock = array('shortDescription' => $docblock);
  151. }
  152. if (is_array($docblock)) {
  153. $docblock = new PhpDocblock($docblock);
  154. } elseif (!$docblock instanceof PhpDocblock) {
  155. throw new Exception\InvalidArgumentException('setDocblock() is expecting either a string, array or an instance of Zend_CodeGenerator_Php_Docblock');
  156. }
  157. $this->_docblock = $docblock;
  158. return $this;
  159. }
  160. /**
  161. * getNamespaceName()
  162. *
  163. * @return string
  164. */
  165. public function getNamespaceName()
  166. {
  167. return $this->_namespaceName;
  168. }
  169. /**
  170. * setNamespaceName()
  171. *
  172. * @param $namespaceName
  173. * @return Zend\CodeGenerator\Php\PhpClass
  174. */
  175. public function setNamespaceName($namespaceName)
  176. {
  177. $this->_namespaceName = $namespaceName;
  178. return $this;
  179. }
  180. /**
  181. * getDocblock()
  182. *
  183. * @return \Zend\CodeGenerator\PhpDocblock
  184. */
  185. public function getDocblock()
  186. {
  187. return $this->_docblock;
  188. }
  189. /**
  190. * setName()
  191. *
  192. * @param string $name
  193. * @return \Zend\CodeGenerator\Php\PhpClass
  194. */
  195. public function setName($name)
  196. {
  197. if (strstr($name, '\\')) {
  198. $namespace = substr($name, 0, strrpos($name, '\\'));
  199. $name = substr($name, strrpos($name, '\\') + 1);
  200. $this->setNamespaceName($namespace);
  201. }
  202. $this->_name = $name;
  203. return $this;
  204. }
  205. /**
  206. * getName()
  207. *
  208. * @return string
  209. */
  210. public function getName()
  211. {
  212. return $this->_name;
  213. }
  214. /**
  215. * setAbstract()
  216. *
  217. * @param bool $isAbstract
  218. * @return \Zend\CodeGenerator\Php\PhpClass
  219. */
  220. public function setAbstract($isAbstract)
  221. {
  222. $this->_isAbstract = ($isAbstract) ? true : false;
  223. return $this;
  224. }
  225. /**
  226. * isAbstract()
  227. *
  228. * @return bool
  229. */
  230. public function isAbstract()
  231. {
  232. return $this->_isAbstract;
  233. }
  234. /**
  235. * setExtendedClass()
  236. *
  237. * @param string $extendedClass
  238. * @return \Zend\CodeGenerator\Php\PhpClass
  239. */
  240. public function setExtendedClass($extendedClass)
  241. {
  242. $this->_extendedClass = $extendedClass;
  243. return $this;
  244. }
  245. /**
  246. * getExtendedClass()
  247. *
  248. * @return string
  249. */
  250. public function getExtendedClass()
  251. {
  252. return $this->_extendedClass;
  253. }
  254. /**
  255. * setImplementedInterfaces()
  256. *
  257. * @param array $implementedInterfaces
  258. * @return \Zend\CodeGenerator\Php\PhpClass
  259. */
  260. public function setImplementedInterfaces(array $implementedInterfaces)
  261. {
  262. $this->_implementedInterfaces = $implementedInterfaces;
  263. return $this;
  264. }
  265. /**
  266. * getImplementedInterfaces
  267. *
  268. * @return array
  269. */
  270. public function getImplementedInterfaces()
  271. {
  272. return $this->_implementedInterfaces;
  273. }
  274. /**
  275. * setProperties()
  276. *
  277. * @param array $properties
  278. * @return \Zend\CodeGenerator\Php\PhpClass
  279. */
  280. public function setProperties(array $properties)
  281. {
  282. foreach ($properties as $property) {
  283. $this->setProperty($property);
  284. }
  285. return $this;
  286. }
  287. /**
  288. * setProperty()
  289. *
  290. * @param array|\Zend\CodeGenerator\Php\PhpProperty $property
  291. * @return \Zend\CodeGenerator\Php\PhpClass
  292. */
  293. public function setProperty($property)
  294. {
  295. if (is_array($property)) {
  296. $property = new PhpProperty($property);
  297. } elseif (!$property instanceof PhpProperty) {
  298. throw new Exception\InvalidArgumentException('setProperty() expects either an array of property options or an instance of Zend_CodeGenerator_Php_Property');
  299. }
  300. $propertyName = $property->getName();
  301. if (isset($this->_properties[$propertyName])) {
  302. throw new Exception\InvalidArgumentException('A property by name ' . $propertyName . ' already exists in this class.');
  303. }
  304. $this->_properties[$propertyName] = $property;
  305. return $this;
  306. }
  307. /**
  308. * getProperties()
  309. *
  310. * @return array
  311. */
  312. public function getProperties()
  313. {
  314. return $this->_properties;
  315. }
  316. /**
  317. * getProperty()
  318. *
  319. * @param string $propertyName
  320. * @return \Zend\CodeGenerator\Php\PhpProperty
  321. */
  322. public function getProperty($propertyName)
  323. {
  324. foreach ($this->_properties as $property) {
  325. if ($property->getName() == $propertyName) {
  326. return $property;
  327. }
  328. }
  329. return false;
  330. }
  331. /**
  332. * hasProperty()
  333. *
  334. * @param string $propertyName
  335. * @return bool
  336. */
  337. public function hasProperty($propertyName)
  338. {
  339. return isset($this->_properties[$propertyName]);
  340. }
  341. /**
  342. * setMethods()
  343. *
  344. * @param array $methods
  345. * @return \Zend\CodeGenerator\Php\PhpClass
  346. */
  347. public function setMethods(array $methods)
  348. {
  349. foreach ($methods as $method) {
  350. $this->setMethod($method);
  351. }
  352. return $this;
  353. }
  354. /**
  355. * setMethod()
  356. *
  357. * @param array|\Zend\CodeGenerator\Php\PhpMethod $method
  358. * @return \Zend\CodeGenerator\Php\PhpClass
  359. */
  360. public function setMethod($method)
  361. {
  362. if (is_array($method)) {
  363. $method = new PhpMethod($method);
  364. } elseif (!$method instanceof PhpMethod) {
  365. throw new Exception\InvalidArgumentException('setMethod() expects either an array of method options or an instance of Zend\CodeGenerator\Php\Method');
  366. }
  367. $methodName = $method->getName();
  368. if (isset($this->_methods[$methodName])) {
  369. throw new Exception\InvalidArgumentException('A method by name ' . $methodName . ' already exists in this class.');
  370. }
  371. $this->_methods[$methodName] = $method;
  372. return $this;
  373. }
  374. /**
  375. * getMethods()
  376. *
  377. * @return array
  378. */
  379. public function getMethods()
  380. {
  381. return $this->_methods;
  382. }
  383. /**
  384. * getMethod()
  385. *
  386. * @param string $methodName
  387. * @return \Zend\CodeGenerator\Php\PhpMethod
  388. */
  389. public function getMethod($methodName)
  390. {
  391. foreach ($this->_methods as $method) {
  392. if ($method->getName() == $methodName) {
  393. return $method;
  394. }
  395. }
  396. return false;
  397. }
  398. /**
  399. * hasMethod()
  400. *
  401. * @param string $methodName
  402. * @return bool
  403. */
  404. public function hasMethod($methodName)
  405. {
  406. return isset($this->_methods[$methodName]);
  407. }
  408. /**
  409. * isSourceDirty()
  410. *
  411. * @return bool
  412. */
  413. public function isSourceDirty()
  414. {
  415. if (($docblock = $this->getDocblock()) && $docblock->isSourceDirty()) {
  416. return true;
  417. }
  418. foreach ($this->_properties as $property) {
  419. if ($property->isSourceDirty()) {
  420. return true;
  421. }
  422. }
  423. foreach ($this->_methods as $method) {
  424. if ($method->isSourceDirty()) {
  425. return true;
  426. }
  427. }
  428. return parent::isSourceDirty();
  429. }
  430. /**
  431. * generate()
  432. *
  433. * @return string
  434. */
  435. public function generate()
  436. {
  437. if (!$this->isSourceDirty()) {
  438. $output = $this->getSourceContent();
  439. if (!empty($output)) {
  440. return $output;
  441. }
  442. }
  443. $output = '';
  444. if (null !== ($namespace = $this->getNamespaceName())) {
  445. $output .= "/** @namespace */" . self::LINE_FEED;
  446. $output .= 'namespace ' . $namespace . ';' . self::LINE_FEED . self::LINE_FEED;
  447. }
  448. if (null !== ($docblock = $this->getDocblock())) {
  449. $docblock->setIndentation('');
  450. $output .= $docblock->generate();
  451. }
  452. if ($this->isAbstract()) {
  453. $output .= 'abstract ';
  454. }
  455. $output .= 'class ' . $this->getName();
  456. if ( !empty( $this->_extendedClass) ) {
  457. $output .= ' extends ' . $this->_extendedClass;
  458. }
  459. $implemented = $this->getImplementedInterfaces();
  460. if (!empty($implemented)) {
  461. $output .= ' implements ' . implode(', ', $implemented);
  462. }
  463. $output .= self::LINE_FEED . '{' . self::LINE_FEED . self::LINE_FEED;
  464. $properties = $this->getProperties();
  465. if (!empty($properties)) {
  466. foreach ($properties as $property) {
  467. $output .= $property->generate() . self::LINE_FEED . self::LINE_FEED;
  468. }
  469. }
  470. $methods = $this->getMethods();
  471. if (!empty($methods)) {
  472. foreach ($methods as $method) {
  473. $output .= $method->generate() . self::LINE_FEED;
  474. }
  475. }
  476. $output .= self::LINE_FEED . '}' . self::LINE_FEED;
  477. return $output;
  478. }
  479. /**
  480. * _init() - is called at construction time
  481. *
  482. */
  483. protected function _init()
  484. {
  485. $this->_properties = new PhpMember\MemberContainer(PhpMember\MemberContainer::TYPE_PROPERTY);
  486. $this->_methods = new PhpMember\MemberContainer(PhpMember\MemberContainer::TYPE_METHOD);
  487. }
  488. }