| 165 | | // Use reflection to find information |
| 166 | | $reflection = new ReflectionClass($matches[1]); |
| 167 | | |
| 168 | | // Class definition |
| 169 | | $class = array |
| 170 | | ( |
| 171 | | 'name' => $reflection->getName(), |
| 172 | | 'about' => $reflection->getDocComment(), |
| 173 | | 'final' => $reflection->isFinal(), |
| 174 | | 'abstract' => $reflection->isAbstract(), |
| 175 | | 'interface' => $reflection->isInterface(), |
| 176 | | 'extends' => '', |
| 177 | | 'implements' => array(), |
| 178 | | 'methods' => array() |
| 179 | | ); |
| 180 | | |
| 181 | | if ($implements = $reflection->getInterfaces()) |
| 182 | | { |
| 183 | | foreach($implements as $interface) |
| 184 | | { |
| 185 | | // Get implemented interfaces |
| 186 | | $class['implements'][] = $interface->getName(); |
| 187 | | } |
| 188 | | } |
| 189 | | |
| 190 | | if ($parent = $reflection->getParentClass()) |
| 191 | | { |
| 192 | | // Get parent class |
| 193 | | $class['extends'] = $parent->getName(); |
| 194 | | } |
| 195 | | |
| 196 | | if ($methods = $reflection->getMethods()) |
| 197 | | { |
| 198 | | foreach($methods as $method) |
| 199 | | { |
| 200 | | // Don't try to document internal methods |
| 201 | | if ($method->isInternal()) continue; |
| 202 | | |
| 203 | | $class['methods'][] = array |
| 204 | | ( |
| 205 | | 'name' => $method->getName(), |
| 206 | | 'about' => $method->getDocComment(), |
| 207 | | 'final' => $method->isFinal(), |
| 208 | | 'static' => $method->isStatic(), |
| 209 | | 'abstract' => $method->isAbstract(), |
| 210 | | 'visibility' => $this->visibility($method), |
| 211 | | 'parameters' => $this->parameters($method) |
| 212 | | ); |
| 213 | | } |
| 214 | | } |
| 215 | | |
| | 203 | protected function parse_comment($block) |
| | 204 | { |
| | 205 | if (trim($block) == '') |
| | 206 | return $block; |
| | 207 | |
| | 208 | // Explode the lines into an array and trim them |
| | 209 | $block = array_map('trim', explode("\n", $block)); |
| | 210 | |
| | 211 | if (current($block) === '/**') |
| | 212 | { |
| | 213 | // Remove comment opening |
| | 214 | array_shift($block); |
| | 215 | } |
| | 216 | |
| | 217 | if (end($block) === '*/') |
| | 218 | { |
| | 219 | // Remove comment closing |
| | 220 | array_pop($block); |
| | 221 | } |
| | 222 | |
| | 223 | // Start comment |
| | 224 | $comment = array(); |
| | 225 | |
| | 226 | while ($line = array_shift($block)) |
| | 227 | { |
| | 228 | // Remove comment * and trim |
| | 229 | $line = trim(substr($line, 2)); |
| | 230 | |
| | 231 | if (preg_match('/^(?:class|file|method):\s+([a-z]+)/i', $line)) |
| | 232 | { |
| | 233 | // Skip these lines |
| | 234 | continue; |
| | 235 | } |
| | 236 | |
| | 237 | if (substr($line, 0, 1) === '$' AND substr($line, -1) === '$') |
| | 238 | { |
| | 239 | // Skip SVN property inserts |
| | 240 | continue; |
| | 241 | } |
| | 242 | |
| | 243 | if (preg_match('/^(?:license):/i', $line)) |
| | 244 | { |
| | 245 | if (empty($comment['license'])) |
| | 246 | { |
| | 247 | // Create the license block |
| | 248 | $comment['license'] = array(); |
| | 249 | } |
| | 250 | |
| | 251 | // Setup the part |
| | 252 | $part =& $comment['license']; |
| | 253 | |
| | 254 | // End of part |
| | 255 | $end = ''; |
| | 256 | |
| | 257 | // Do not add the license line |
| | 258 | continue; |
| | 259 | } |
| | 260 | |
| | 261 | if (isset($part) AND isset($end)) |
| | 262 | { |
| | 263 | if ($line === $end) |
| | 264 | { |
| | 265 | // This part is over, clear it |
| | 266 | unset($part, $end); |
| | 267 | continue; |
| | 268 | } |
| | 269 | |
| | 270 | if ($line === '') |
| | 271 | { |
| | 272 | $line = "\n"; |
| | 273 | } |
| | 274 | |
| | 275 | // Append the line to the current part |
| | 276 | $part[] = $line; |
| | 277 | } |
| | 278 | else |
| | 279 | { |
| | 280 | // Add the line to the comment |
| | 281 | $comment['about'][] = $line; |
| | 282 | } |
| | 283 | } |
| | 284 | |
| | 285 | foreach($comment as $key => $block) |
| | 286 | { |
| | 287 | // Implode each of the comment blocks |
| | 288 | $comment[$key] = trim(implode("\n", $block)); |
| | 289 | } |
| | 290 | |
| | 291 | return $comment; |
| | 292 | } |
| | 293 | |
| | 294 | protected function parse_class($class) |
| | 295 | { |
| | 296 | // Use reflection to find information |
| | 297 | $reflection = new ReflectionClass($class); |
| | 298 | |
| | 299 | // Class definition |
| | 300 | $class = array |
| | 301 | ( |
| | 302 | 'name' => $reflection->getName(), |
| | 303 | 'comment' => $this->parse_comment($reflection->getDocComment()), |
| | 304 | 'final' => $reflection->isFinal(), |
| | 305 | 'abstract' => $reflection->isAbstract(), |
| | 306 | 'interface' => $reflection->isInterface(), |
| | 307 | 'extends' => '', |
| | 308 | 'implements' => array(), |
| | 309 | 'methods' => array() |
| | 310 | ); |
| | 311 | |
| | 312 | if ($implements = $reflection->getInterfaces()) |
| | 313 | { |
| | 314 | foreach($implements as $interface) |
| | 315 | { |
| | 316 | // Get implemented interfaces |
| | 317 | $class['implements'][] = $interface->getName(); |
| | 318 | } |
| | 319 | } |
| | 320 | |
| | 321 | if ($parent = $reflection->getParentClass()) |
| | 322 | { |
| | 323 | // Get parent class |
| | 324 | $class['extends'] = $parent->getName(); |
| | 325 | } |
| | 326 | |
| | 327 | |
| | 328 | if ($methods = $reflection->getMethods()) |
| | 329 | { |
| | 330 | foreach($methods as $method) |
| | 331 | { |
| | 332 | // Don't try to document internal methods |
| | 333 | if ($method->isInternal()) continue; |
| | 334 | |
| | 335 | $class['methods'][] = array |
| | 336 | ( |
| | 337 | 'name' => $method->getName(), |
| | 338 | 'comment' => $this->parse_comment($method->getDocComment()), |
| | 339 | 'final' => $method->isFinal(), |
| | 340 | 'static' => $method->isStatic(), |
| | 341 | 'abstract' => $method->isAbstract(), |
| | 342 | 'visibility' => $this->visibility($method), |
| | 343 | 'parameters' => $this->parameters($method) |
| | 344 | ); |
| | 345 | } |
| | 346 | } |
| | 347 | |
| | 348 | return $class; |
| | 349 | } |
| | 350 | |