PhpUml

EXPERIMENTAL
Let me knwow by sending a message if someone is working on PHP_UML to improve the 'php to xmi' process.

Description

Task to process phpuml (see: pear.php.net/package/PHP_UML).
PhpUml v1.6.1 is embedded within ant4x.jar.

Installation

If you get error message :
$ php UML.php -h
PHP Warning: require_once(PEAR/Exception.php): failed to open stream: No such file or directory in PHP_UML-1.6.1/UML.php on line 22
PHP Fatal error: require_once(): Failed opening required 'PEAR/Exception.php' (include_path='.:/usr/share/php:/usr/share/pear') in PHP_UML-1.6.1/UML.php on line 22

Please install (linux debian):
$ apt-get install php-pear

PhpUml task parameters

Attribute Description Value Required
file the php input file yes
tofile the xmi output file yes

Examples

/!\ php must be installed on the system and set up in the PATH.

<project name="phpuml task"> 

  <taskdef name="phpuml" 
     classname="net.sourceforge.ant4x.taskdefs.php.PhpUmlTask" 
     classpath="PATH/TO/ant4x.jar"/> 

  <target name="phpuml"> 
    <mkdir dir="gen/uml"/>
    <ant4x:phpuml file="../dev/src/resources/PHP_UML-1.6.1/UML/FileScanner.php" tofile="gen/uml/filescanner.xmi"/>
  </target> 

                    </project>  
FileScanner.php

<?php
/**
 * PHP_UML
 *
 * PHP version 5
 *
 * @category PHP
 * @package  PHP_UML
 * @author   Baptiste Autin
 * @license  http://www.gnu.org/licenses/lgpl.html LGPL License 3
 * @version  SVN: $Revision: 105 $
 * @link     http://pear.php.net/package/PHP_UML
 * @link     http://www.baptisteautin.com/projects/PHP_UML/
 * @since    $Date: 2009-06-04 19:48:27 +0200 (jeu., 04 juin 2009) $
 */


/**
 * A superclass for scanning files and folders. It does nothing but browsing
 * recursively the file system tree, given a list of entry folders. At least
 * one folder must be provided.
 * It can be seen as an extension of RecursiveDirectoryIterator, upon which
 * it is based.
 * 
 * @category PHP
 * @package  PHP_UML
 * @author   Baptiste Autin
 * @license  http://www.gnu.org/licenses/lgpl.html LGPL License 3
 * 
 */
abstract class PHP_UML_FileScanner
{

    /**
     * List of directories to scan
     *
     * @var array
     */
    protected $directories = array();
    
    /**
     * List of files to scan
     *
     * @var array
     */
    protected $files = array();
    
    /**
     * Allowed path-/file-names (possible wildcards are ? and *)
     * 
     * @var array
     */
    protected $matchPatterns = array('*.php');
    
    /**
     * Ignored directories (possible wildcards are ? and *)
     *
     * @var array();
     */
    protected $ignorePatterns = array();


    /**
     * Constructor
     *
     */
    public function __construct()
    {
    }

    /**
     * This function will be called every time the scanner meets
     * a new file (while it looks into the folders), as well as for
     * each file defined in the property $files.
     * It's up to the subclass to define the treatment to be done.
     *
     * @param mixed  $basedir  Directory path
     *
     * @param string $filename File name
     */
    abstract function tickFile($basedir, $filename);

    /**
     * Starts the scan
     *
     */
    public function scan()
    {
        // We parse the directories
        foreach ($this->directories as $pathItem) {
            $baseDir  = realpath($pathItem);
            $trailing = substr($baseDir, -1);

            if ($baseDir != false &amp;&amp; is_dir($baseDir) &amp;&amp; is_readable($baseDir)) {

                if ($trailing != '/' &amp;&amp; $trailing != '\\')
                     $baseDir .= DIRECTORY_SEPARATOR;
                
                $objects = new RecursiveIteratorIterator(
                    new PHP_UML_FilePatternFilterIterator(
                        new RecursiveDirectoryIterator($baseDir), $this->ignorePatterns, $this->matchPatterns
                    )
                );

                $baseDirPos = strlen($baseDir);
                foreach ($objects as $ptr) {
                    $relativePath = substr($ptr->getPathname(), $baseDirPos);
                    $this->tickFile($baseDir, $relativePath);
                }
            }
            else
                $this->raiseUnknownFolderException($pathItem);
        }

        // We parse the files
        foreach ($this->files as $filenameItem) {
            $filenameItem = realpath($filenameItem);
            $baseDir      = dirname($filenameItem).DIRECTORY_SEPARATOR;
            $baseName     = basename($filenameItem);
            if ($filenameItem != false)
                $this->tickFile($baseDir, $baseName);
        }

    }

    /**
     * Can be overriden to treat unknown folder exception
     *
     * @param string $basedir Directory name
     */
    public function raiseUnknownFolderException($basedir)
    {
    }
    
    public function setFiles(array $files)
    {
        $this->files = $files;
    }
    
    public function setDirectories(array $directories)
    {
        $this->directories = $directories;
    }
    
    public function setMatchPatterns(array $patterns)
    {
        $this->matchPatterns = $patterns;
    }
    
    public function setIgnorePatterns(array $patterns)
    {
        $this->ignorePatterns = $patterns;
    }
}
                      ?>  
filescanner.xmi

<?xml version="1.0" encoding="iso-8859-1"?><xmi:XMI xmi:version="2.1" 
            xmlns:uml="http://schema.omg.org/spec/UML/2.1.2"
            xmlns:xmi="http://schema.omg.org/spec/XMI/2.1"
            xmlns:php="http://schemas/phpdoc/52f4c1050fecc">
                <xmi:Documentation exporter="PEAR\PHP_UML"/><uml:Model xmi:type="uml:Model" name="default"
            xmi:id="52f4c1050c636"  visibility="public" isAbstract="false" ><packagedElement xmi:type="uml:DataType" xmi:id="52f4c1050c74f" name="mixed"><ownedComment xmi:type="uml:Comment"
                xmi:id="52f4c1050ff33" annotatedElement="52f4c1050c74f"><body>Internal PHP type.</body></ownedComment></packagedElement><packagedElement xmi:type="uml:DataType" xmi:id="52f4c1050c9a9" name="array"><ownedComment xmi:type="uml:Comment"
                xmi:id="52f4c1050ff89" annotatedElement="52f4c1050c9a9"><body>Internal PHP type.</body></ownedComment></packagedElement><packagedElement xmi:type="uml:DataType" xmi:id="52f4c1050ca37" name="string"><ownedComment xmi:type="uml:Comment"
                xmi:id="52f4c1050ffd3" annotatedElement="52f4c1050ca37"><body>Internal PHP type.</body></ownedComment></packagedElement><packagedElement xmi:type="uml:DataType" xmi:id="52f4c1050cabf" name="int"><ownedComment xmi:type="uml:Comment"
                xmi:id="52f4c1051001b" annotatedElement="52f4c1050cabf"><body>Internal PHP type.</body></ownedComment></packagedElement><packagedElement xmi:type="uml:DataType" xmi:id="52f4c1050cb90" name="integer"><ownedComment xmi:type="uml:Comment"
                xmi:id="52f4c10510063" annotatedElement="52f4c1050cb90"><body>Internal PHP type.</body></ownedComment></packagedElement><packagedElement xmi:type="uml:DataType" xmi:id="52f4c1050cc18" name="bool"><ownedComment xmi:type="uml:Comment"
                xmi:id="52f4c105100ab" annotatedElement="52f4c1050cc18"><body>Internal PHP type.</body></ownedComment></packagedElement><packagedElement xmi:type="uml:DataType" xmi:id="52f4c1050cca1" name="boolean"><ownedComment xmi:type="uml:Comment"
                xmi:id="52f4c105100f3" annotatedElement="52f4c1050cca1"><body>Internal PHP type.</body></ownedComment></packagedElement><packagedElement xmi:type="uml:DataType" xmi:id="52f4c1050cd29" name="float"><ownedComment xmi:type="uml:Comment"
                xmi:id="52f4c1051013b" annotatedElement="52f4c1050cd29"><body>Internal PHP type.</body></ownedComment></packagedElement><packagedElement xmi:type="uml:DataType" xmi:id="52f4c1050cdb2" name="void"><ownedComment xmi:type="uml:Comment"
                xmi:id="52f4c10510187" annotatedElement="52f4c1050cdb2"><body>Internal PHP type.</body></ownedComment></packagedElement><packagedElement xmi:type="uml:DataType" xmi:id="52f4c1050ce48" name="null"><ownedComment xmi:type="uml:Comment"
                xmi:id="52f4c105101cf" annotatedElement="52f4c1050ce48"><body>Internal PHP type.</body></ownedComment></packagedElement><packagedElement xmi:type="uml:DataType" xmi:id="52f4c1050ced2" name="object"><ownedComment xmi:type="uml:Comment"
                xmi:id="52f4c10510216" annotatedElement="52f4c1050ced2"><body>Internal PHP type.</body></ownedComment></packagedElement><packagedElement xmi:type="uml:DataType" xmi:id="52f4c1050cf5b" name="resource"><ownedComment xmi:type="uml:Comment"
                xmi:id="52f4c1051025e" annotatedElement="52f4c1050cf5b"><body>Internal PHP type.</body></ownedComment></packagedElement><packagedElement xmi:type="uml:Interface"  name="Iterator" xmi:id="52f4c1050d089" visibility="package" isAbstract="true"><ownedComment xmi:type="uml:Comment"
                xmi:id="52f4c105102ad" annotatedElement="52f4c1050d089"><body>Internal PHP interface.</body></ownedComment></packagedElement><packagedElement xmi:type="uml:Interface"  name="Countable" xmi:id="52f4c1050d11b" visibility="package" isAbstract="true"><ownedComment xmi:type="uml:Comment"
                xmi:id="52f4c105102f8" annotatedElement="52f4c1050d11b"><body>Internal PHP interface.</body></ownedComment></packagedElement><packagedElement xmi:type="uml:Class" name="Exception" xmi:id="52f4c1050d1f2" visibility="package"
            isAbstract="false"><ownedComment xmi:type="uml:Comment"
                xmi:id="52f4c10510349" annotatedElement="52f4c1050d1f2"><body>Internal PHP class.</body></ownedComment></packagedElement><packagedElement xmi:type="uml:Package" xmi:id="52f4c1050de9e" name="PHP_UML"><packagedElement xmi:type="uml:Class" name="PHP_UML_FileScanner" xmi:id="52f4c1050df1f" visibility="package"
            isAbstract="true"><ownedAttribute xmi:type="uml:Property" name="$directories" xmi:id="52f4c1050e239" visibility="protected" ><type xmi:idref="52f4c1050c9a9"/><defaultValue xmi:type="uml:LiteralString" xmi:id="52f4c105103a8" value="array()" /><ownedComment xmi:type="uml:Comment"
                xmi:id="52f4c105103f4" annotatedElement="52f4c1050e239"><body>List of directories to scan</body></ownedComment></ownedAttribute><ownedAttribute xmi:type="uml:Property" name="$files" xmi:id="52f4c1050e36d" visibility="protected" ><type xmi:idref="52f4c1050c9a9"/><defaultValue xmi:type="uml:LiteralString" xmi:id="52f4c1051043b" value="array()" /><ownedComment xmi:type="uml:Comment"
                xmi:id="52f4c10510481" annotatedElement="52f4c1050e36d"><body>List of files to scan</body></ownedComment></ownedAttribute><ownedAttribute xmi:type="uml:Property" name="$matchPatterns" xmi:id="52f4c1050e481" visibility="protected" ><type xmi:idref="52f4c1050c9a9"/><defaultValue xmi:type="uml:LiteralString" xmi:id="52f4c105104c6" value="array(&#039;*.php&#039;)" /><ownedComment xmi:type="uml:Comment"
                xmi:id="52f4c1051050c" annotatedElement="52f4c1050e481"><body>Allowed path-/file-names (possible wildcards are ? and *)</body></ownedComment></ownedAttribute><ownedAttribute xmi:type="uml:Property" name="$ignorePatterns" xmi:id="52f4c1050e598" visibility="protected" ><type xmi:idref="52f4c1050c9a9"/><defaultValue xmi:type="uml:LiteralString" xmi:id="52f4c10510554" value="array()" /><ownedComment xmi:type="uml:Comment"
                xmi:id="52f4c10510599" annotatedElement="52f4c1050e598"><body>Ignored directories (possible wildcards are ? and *)</body></ownedComment></ownedAttribute><ownedOperation xmi:id="52f4c1050e729" 
            name="__construct" visibility="public" ><ownedParameter xmi:id="52f4c1050e811" name="return" direction="return"><type xmi:idref="52f4c1050cdb2"/></ownedParameter><ownedComment xmi:type="uml:Comment"
                xmi:id="52f4c1051062d" annotatedElement="52f4c1050e729"><body>Constructor</body></ownedComment></ownedOperation><ownedOperation xmi:id="52f4c1050e883" 
            name="tickFile" visibility="public"  isAbstract="true"><ownedParameter xmi:id="52f4c1050e9d2" name="return" direction="return"><type xmi:idref="52f4c1050cdb2"/></ownedParameter><ownedParameter xmi:id="52f4c1050ea1c" name="$basedir" direction="in"><type xmi:idref="52f4c1050c74f"/></ownedParameter><ownedParameter xmi:id="52f4c1050ea83" name="$filename" direction="in"><type xmi:idref="52f4c1050ca37"/></ownedParameter><ownedComment xmi:type="uml:Comment"
                xmi:id="52f4c10510743" annotatedElement="52f4c1050e883"><body>This function will be called every time the scanner meets a new file (while it looks into the folders), as well as for each file defined in the property $files.
It's up to the subclass to define the treatment to be done.</body></ownedComment></ownedOperation><ownedOperation xmi:id="52f4c1050eae8" 
            name="scan" visibility="public" ><ownedParameter xmi:id="52f4c1050eb89" name="return" direction="return"><type xmi:idref="52f4c1050cdb2"/></ownedParameter><ownedComment xmi:type="uml:Comment"
                xmi:id="52f4c105107da" annotatedElement="52f4c1050eae8"><body>Starts the scan</body></ownedComment></ownedOperation><ownedOperation xmi:id="52f4c1050ed9b" 
            name="raiseUnknownFolderException" visibility="public" ><ownedParameter xmi:id="52f4c1050ee95" name="return" direction="return"><type xmi:idref="52f4c1050cdb2"/></ownedParameter><ownedParameter xmi:id="52f4c1050eede" name="$basedir" direction="in"><type xmi:idref="52f4c1050ca37"/></ownedParameter><ownedComment xmi:type="uml:Comment"
                xmi:id="52f4c105108a9" annotatedElement="52f4c1050ed9b"><body>Can be overriden to treat unknown folder exception</body></ownedComment></ownedOperation><ownedOperation xmi:id="52f4c1050ef42" 
            name="setFiles" visibility="public" ><ownedParameter xmi:id="52f4c1050ef9a" name="return" direction="return"><type xmi:idref="52f4c1050cdb2"/></ownedParameter><ownedParameter xmi:id="52f4c1050efe4" name="$files" direction="in"><type xmi:idref="52f4c1050c9a9"/></ownedParameter></ownedOperation><ownedOperation xmi:id="52f4c1050f05f" 
            name="setDirectories" visibility="public" ><ownedParameter xmi:id="52f4c1050f0b1" name="return" direction="return"><type xmi:idref="52f4c1050cdb2"/></ownedParameter><ownedParameter xmi:id="52f4c1050f0fa" name="$directories" direction="in"><type xmi:idref="52f4c1050c9a9"/></ownedParameter></ownedOperation><ownedOperation xmi:id="52f4c1050f169" 
            name="setMatchPatterns" visibility="public" ><ownedParameter xmi:id="52f4c1050f1b9" name="return" direction="return"><type xmi:idref="52f4c1050cdb2"/></ownedParameter><ownedParameter xmi:id="52f4c1050f203" name="$patterns" direction="in"><type xmi:idref="52f4c1050c9a9"/></ownedParameter></ownedOperation><ownedOperation xmi:id="52f4c1050f270" 
            name="setIgnorePatterns" visibility="public" ><ownedParameter xmi:id="52f4c1050f2c0" name="return" direction="return"><type xmi:idref="52f4c1050cdb2"/></ownedParameter><ownedParameter xmi:id="52f4c1050f30a" name="$patterns" direction="in"><type xmi:idref="52f4c1050c9a9"/></ownedParameter></ownedOperation><ownedComment xmi:type="uml:Comment"
                xmi:id="52f4c10510b30" annotatedElement="52f4c1050df1f"><body>A superclass for scanning files and folders. It does nothing but browsing recursively the file system tree, given a list of entry folders. At least one folder must be provided.
                        It can be seen as an extension of RecursiveDirectoryIterator, upon which it is based.</body></ownedComment></packagedElement></packagedElement></uml:Model></xmi:XMI>