Overview

Namespaces

  • Pharborist
    • Constants
    • ControlStructures
    • Exceptions
    • Functions
    • Generators
    • Namespaces
    • Objects
    • Operators
    • Types
    • Variables

Classes

  • Pharborist\Variables\CompoundVariableNode
  • Pharborist\Variables\GlobalStatementNode
  • Pharborist\Variables\ReferenceVariableNode
  • Pharborist\Variables\StaticVariableNode
  • Pharborist\Variables\StaticVariableStatementNode
  • Pharborist\Variables\VariableNode
  • Pharborist\Variables\VariableVariableNode

Interfaces

  • Pharborist\Variables\VariableExpressionNode
  • Overview
  • Namespace
  • Class
  1: <?php
  2: namespace Pharborist\Objects;
  3: 
  4: use Pharborist\CommaListNode;
  5: use Pharborist\DocCommentTrait;
  6: use Pharborist\ExpressionNode;
  7: use Pharborist\Filter;
  8: use Pharborist\FormatterFactory;
  9: use Pharborist\Functions\FunctionDeclarationNode;
 10: use Pharborist\Namespaces\IdentifierNameTrait;
 11: use Pharborist\Namespaces\NameNode;
 12: use Pharborist\NodeCollection;
 13: use Pharborist\StatementBlockNode;
 14: use Pharborist\StatementNode;
 15: use Pharborist\Token;
 16: 
 17: /**
 18:  * Base class for ClassNode and TraitNode.
 19:  *
 20:  * @see ClassNode
 21:  * @see TraitNode
 22:  */
 23: abstract class SingleInheritanceNode extends StatementNode {
 24:   use DocCommentTrait;
 25:   use IdentifierNameTrait;
 26: 
 27:   /**
 28:    * @var \Pharborist\Namespaces\NameNode
 29:    */
 30:   protected $extends;
 31: 
 32:   /**
 33:    * @var CommaListNode
 34:    */
 35:   protected $implements;
 36: 
 37:   /**
 38:    * @var StatementBlockNode
 39:    */
 40:   protected $statements;
 41: 
 42:   /**
 43:    * @return NameNode
 44:    */
 45:   public function getExtends() {
 46:     return $this->extends;
 47:   }
 48: 
 49:   /**
 50:    * @param string|\Pharborist\Namespaces\NameNode $extends
 51:    * @return $this
 52:    */
 53:   public function setExtends($extends) {
 54:     if ($extends === NULL) {
 55:       if (isset($this->extends)) {
 56:         // Remove whitespace after extends keyword.
 57:         $this->extends->previous()->remove();
 58:         // Remove extends keyword.
 59:         $this->extends->previous()->remove();
 60:         // Remove whitespace before extends keyword.
 61:         $this->extends->previous()->remove();
 62:         // Remove extends namespace.
 63:         $this->extends->remove();
 64:       }
 65:     }
 66:     else {
 67:       if (is_string($extends)) {
 68:         $extends = NameNode::create($extends);
 69:       }
 70:       if (isset($this->extends)) {
 71:         $this->extends->replaceWith($extends);
 72:       }
 73:       else {
 74:         $this->name->after([
 75:           Token::space(),
 76:           Token::_extends(),
 77:           Token::space(),
 78:           $extends
 79:         ]);
 80:       }
 81:       $this->extends = $extends;
 82:     }
 83:     return $this;
 84:   }
 85: 
 86:   /**
 87:    * @return CommaListNode
 88:    */
 89:   public function getImplementList() {
 90:     return $this->implements;
 91:   }
 92: 
 93:   /**
 94:    * @return NodeCollection|NameNode[]
 95:    */
 96:   public function getImplements() {
 97:     return $this->implements->getItems();
 98:   }
 99: 
100:   /**
101:    * @param string|NameNode|CommaListNode|array|NULL $implements
102:    * @throws \InvalidArgumentException
103:    * @return $this
104:    */
105:   public function setImplements($implements) {
106:     if ($implements === NULL) {
107:       if (isset($this->implements)) {
108:         // Remove whitespace after implements keyword.
109:         $this->implements->previous()->remove();
110:         // Remove implements keyword
111:         $this->implements->previous()->remove();
112:         // Remove whitespace before implements keyword.
113:         $this->implements->previous()->remove();
114:         // Remove implements list.
115:         $this->implements->remove();
116:       }
117:     }
118:     else {
119:       // Type conversions.
120:       if (is_string($implements)) {
121:         $implements = NameNode::create($implements);
122:       }
123:       if ($implements instanceof NameNode) {
124:         $implementList = new CommaListNode();
125:         $implementList->append($implements);
126:         $implements = $implementList;
127:       }
128:       if (is_array($implements)) {
129:         $implementList = new CommaListNode();
130:         foreach ($implements as $implement) {
131:           if (is_string($implement)) {
132:             $implementList->append(NameNode::create($implement));
133:           }
134:           elseif ($implement instanceof NameNode) {
135:             $implementList->append($implement);
136:           }
137:           else {
138:             throw new \InvalidArgumentException('Invalid $implements argument');
139:           }
140:         }
141:         $implements = $implementList;
142:       }
143:       // Set implements.
144:       if (isset($this->implements)) {
145:         $this->implements->replaceWith($implements);
146:       }
147:       else {
148:         $after = isset($this->extends) ? $this->extends : $this->name;
149:         $after->after([
150:           Token::space(),
151:           Token::_implements(),
152:           Token::space(),
153:           $implements
154:         ]);
155:       }
156:       $this->implements = $implements;
157:     }
158:     return $this;
159:   }
160: 
161:   /**
162:    * @return StatementBlockNode
163:    */
164:   public function getBody() {
165:     return $this->statements;
166:   }
167: 
168:   /**
169:    * @return NodeCollection|ClassStatementNode[]
170:    */
171:   public function getStatements() {
172:     return $this->statements->getStatements();
173:   }
174: 
175:   /**
176:    * Adds a method to a class/trait.
177:    *
178:    * @param \Pharborist\Functions\FunctionDeclarationNode|\Pharborist\Objects\ClassMethodNode|string $method
179:    *  The method to append. Can either be an existing method, a function (which
180:    *  will be converted to a public method), or a string (a new public method
181:    *  will be created with that name).
182:    *
183:    * @return $this
184:    */
185:   public function appendMethod($method) {
186:     if ($method instanceof FunctionDeclarationNode) {
187:       $method = ClassMethodNode::fromFunction($method);
188:     }
189:     elseif (is_string($method)) {
190:       $method = ClassMethodNode::create($method);
191:     }
192:     $this->statements->lastChild()->before($method);
193:     FormatterFactory::format($this);
194:     return $this;
195:   }
196: 
197:   /**
198:    * Returns if the class/trait has the named property, regardless of
199:    * visibility.
200:    *
201:    * @param string $name
202:    *  The property name, with or without a leading $.
203:    *
204:    * @return boolean
205:    */
206:   public function hasProperty($name) {
207:     return in_array(ltrim($name, '$'), $this->getPropertyNames());
208:   }
209: 
210:   /**
211:    * Returns the names of all class/trait properties, regardless of visibility.
212:    *
213:    * @return string[]
214:    */
215:   public function getPropertyNames() {
216:     return array_map(function (ClassMemberNode $property) {
217:       return ltrim($property->getName(), '$');
218:     }, $this->getAllProperties()->toArray());
219:   }
220: 
221:   /**
222:    * @return \Pharborist\NodeCollection
223:    */
224:   public function getAllProperties() {
225:     $properties = [];
226:     /** @var ClassMemberListNode $node */
227:     foreach ($this->statements->children(Filter::isInstanceOf('\Pharborist\Objects\ClassMemberListNode')) as $node) {
228:       $properties = array_merge($properties, $node->getMembers()->toArray());
229:     }
230:     return new NodeCollection($properties, FALSE);
231:   }
232: 
233:   /**
234:    * Returns if the class has the named method, regardless of visibility.
235:    *
236:    * @param string $name
237:    *  The method name.
238:    *
239:    * @return boolean
240:    */
241:   public function hasMethod($name) {
242:     return in_array($name, $this->getMethodNames());
243:   }
244: 
245:   /**
246:    * Returns the names of all class methods, regardless of visibility.
247:    *
248:    * @return string[]
249:    */
250:   public function getMethodNames() {
251:     return array_map(function (ClassMethodNode $node) {
252:       return $node->getName()->getText();
253:     }, $this->getAllMethods()->toArray());
254:   }
255: 
256:   /**
257:    * @return NodeCollection|ClassMethodNode[]
258:    */
259:   public function getAllMethods() {
260:     return $this->statements->children(Filter::isInstanceOf('\Pharborist\Objects\ClassMethodNode'));
261:   }
262: 
263:   /**
264:    * Returns a property by name, if it exists.
265:    *
266:    * @param string $name
267:    *  The property name, with or without the $.
268:    *
269:    * @return ClassMemberNode|NULL
270:    */
271:   public function getProperty($name) {
272:     $name = ltrim($name, '$');
273: 
274:     $properties = $this
275:       ->getAllProperties()
276:       ->filter(function (ClassMemberNode $property) use ($name) {
277:         return ltrim($property->getName(), '$') === $name;
278:       });
279:     return $properties->isEmpty() ? NULL : $properties[0];
280:   }
281: 
282:   /**
283:    * Returns a method by name, if it exists.
284:    *
285:    * @param string $name
286:    *  The method name.
287:    *
288:    * @return ClassMethodNode|NULL
289:    */
290:   public function getMethod($name) {
291:     $methods = $this
292:       ->getAllMethods()
293:       ->filter(function (ClassMethodNode $method) use ($name) {
294:         return $method->getName()->getText() === $name;
295:       });
296:     return $methods->isEmpty() ? NULL : $methods[0];
297:   }
298: 
299:   /**
300:    * Creates a new property in this class.
301:    *
302:    * @see ClassMemberNode::create
303:    *
304:    * @param string $name
305:    * @param ExpressionNode $value
306:    * @param string $visibility
307:    *
308:    * @return $this
309:    */
310:   public function createProperty($name, ExpressionNode $value = NULL, $visibility = 'public') {
311:     return $this->appendProperty(ClassMemberNode::create($name, $value, $visibility));
312:   }
313: 
314:   /**
315:    * Add property to class.
316:    *
317:    * @param string|ClassMemberListNode $property
318:    * @return $this
319:    */
320:   public function appendProperty($property) {
321:     if (is_string($property)) {
322:       $property = ClassMemberListNode::create($property);
323:     }
324:     $properties = $this->statements->children(Filter::isInstanceOf('\Pharborist\ClassMemberListNode'));
325:     if ($properties->count() === 0) {
326:       $this->statements->firstChild()->after($property);
327:     }
328:     else {
329:       $properties->last()->after($property);
330:     }
331:     FormatterFactory::format($this);
332:     return $this;
333:   }
334: }
335: 
Pharborist API documentation generated by ApiGen