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

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

https://github.com/Shreef/zf2
PHP | 566 lines | 428 code | 32 blank | 106 comment | 12 complexity | 2ee3be01a5780476c9d50bfb49929400 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-2010 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-2010 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('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. $propertyName = $property->getName();
  298. } elseif ($property instanceof PhpProperty) {
  299. $propertyName = $property->getName();
  300. } else {
  301. throw new Exception('setProperty() expects either an array of property options or an instance of Zend_CodeGenerator_Php_Property');
  302. }
  303. if (isset($this->_properties[$propertyName])) {
  304. throw new Exception('A property by name ' . $propertyName . ' already exists in this class.');
  305. }
  306. $this->_properties[$propertyName] = $property;
  307. return $this;
  308. }
  309. /**
  310. * getProperties()
  311. *
  312. * @return array
  313. */
  314. public function getProperties()
  315. {
  316. return $this->_properties;
  317. }
  318. /**
  319. * getProperty()
  320. *
  321. * @param string $propertyName
  322. * @return \Zend\CodeGenerator\Php\PhpProperty
  323. */
  324. public function getProperty($propertyName)
  325. {
  326. foreach ($this->_properties as $property) {
  327. if ($property->getName() == $propertyName) {
  328. return $property;
  329. }
  330. }
  331. return false;
  332. }
  333. /**
  334. * hasProperty()
  335. *
  336. * @param string $propertyName
  337. * @return bool
  338. */
  339. public function hasProperty($propertyName)
  340. {
  341. return isset($this->_properties[$propertyName]);
  342. }
  343. /**
  344. * setMethods()
  345. *
  346. * @param array $methods
  347. * @return \Zend\CodeGenerator\Php\PhpClass
  348. */
  349. public function setMethods(Array $methods)
  350. {
  351. foreach ($methods as $method) {
  352. $this->setMethod($method);
  353. }
  354. return $this;
  355. }
  356. /**
  357. * setMethod()
  358. *
  359. * @param array|\Zend\CodeGenerator\Php\PhpMethod $method
  360. * @return \Zend\CodeGenerator\Php\PhpClass
  361. */
  362. public function setMethod($method)
  363. {
  364. if (is_array($method)) {
  365. $method = new PhpMethod($method);
  366. $methodName = $method->getName();
  367. } elseif ($method instanceof PhpMethod) {
  368. $methodName = $method->getName();
  369. } else {
  370. throw new Exception('setMethod() expects either an array of method options or an instance of Zend\CodeGenerator\Php\Method');
  371. }
  372. if (isset($this->_methods[$methodName])) {
  373. throw new Exception('A method by name ' . $methodName . ' already exists in this class.');
  374. }
  375. $this->_methods[$methodName] = $method;
  376. return $this;
  377. }
  378. /**
  379. * getMethods()
  380. *
  381. * @return array
  382. */
  383. public function getMethods()
  384. {
  385. return $this->_methods;
  386. }
  387. /**
  388. * getMethod()
  389. *
  390. * @param string $methodName
  391. * @return \Zend\CodeGenerator\Php\PhpMethod
  392. */
  393. public function getMethod($methodName)
  394. {
  395. foreach ($this->_methods as $method) {
  396. if ($method->getName() == $methodName) {
  397. return $method;
  398. }
  399. }
  400. return false;
  401. }
  402. /**
  403. * hasMethod()
  404. *
  405. * @param string $methodName
  406. * @return bool
  407. */
  408. public function hasMethod($methodName)
  409. {
  410. return isset($this->_methods[$methodName]);
  411. }
  412. /**
  413. * isSourceDirty()
  414. *
  415. * @return bool
  416. */
  417. public function isSourceDirty()
  418. {
  419. if (($docblock = $this->getDocblock()) && $docblock->isSourceDirty()) {
  420. return true;
  421. }
  422. foreach ($this->_properties as $property) {
  423. if ($property->isSourceDirty()) {
  424. return true;
  425. }
  426. }
  427. foreach ($this->_methods as $method) {
  428. if ($method->isSourceDirty()) {
  429. return true;
  430. }
  431. }
  432. return parent::isSourceDirty();
  433. }
  434. /**
  435. * generate()
  436. *
  437. * @return string
  438. */
  439. public function generate()
  440. {
  441. if (!$this->isSourceDirty()) {
  442. $output = $this->getSourceContent();
  443. if (!empty($output)) {
  444. return $output;
  445. }
  446. }
  447. $output = '';
  448. if (null !== ($namespace = $this->getNamespaceName())) {
  449. $output .= "/** @namespace */" . self::LINE_FEED;
  450. $output .= 'namespace ' . $namespace . ';' . self::LINE_FEED . self::LINE_FEED;
  451. }
  452. if (null !== ($docblock = $this->getDocblock())) {
  453. $docblock->setIndentation('');
  454. $output .= $docblock->generate();
  455. }
  456. if ($this->isAbstract()) {
  457. $output .= 'abstract ';
  458. }
  459. $output .= 'class ' . $this->getName();
  460. if ( !empty( $this->_extendedClass) ) {
  461. $output .= ' extends ' . $this->_extendedClass;
  462. }
  463. $implemented = $this->getImplementedInterfaces();
  464. if (!empty($implemented)) {
  465. $output .= ' implements ' . implode(', ', $implemented);
  466. }
  467. $output .= self::LINE_FEED . '{' . self::LINE_FEED . self::LINE_FEED;
  468. $properties = $this->getProperties();
  469. if (!empty($properties)) {
  470. foreach ($properties as $property) {
  471. $output .= $property->generate() . self::LINE_FEED . self::LINE_FEED;
  472. }
  473. }
  474. $methods = $this->getMethods();
  475. if (!empty($methods)) {
  476. foreach ($methods as $method) {
  477. $output .= $method->generate() . self::LINE_FEED;
  478. }
  479. }
  480. $output .= self::LINE_FEED . '}' . self::LINE_FEED;
  481. return $output;
  482. }
  483. /**
  484. * _init() - is called at construction time
  485. *
  486. */
  487. protected function _init()
  488. {
  489. $this->_properties = new PhpMember\MemberContainer(PhpMember\MemberContainer::TYPE_PROPERTY);
  490. $this->_methods = new PhpMember\MemberContainer(PhpMember\MemberContainer::TYPE_METHOD);
  491. }
  492. }