Builder.php 6.68 KB
Newer Older
lsmith's avatar
lsmith committed
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34
<?php
/*
 *  $Id$
 *
 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
 * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
 * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
 * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
 * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
 * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
 * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
 * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
 * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
 * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
 *
 * This software consists of voluntary contributions made by many individuals
 * and is licensed under the LGPL. For more information, see
 * <http://www.phpdoctrine.com>.
 */

/**
 * Doctrine_Import_Builder
 * Import builder is responsible of building Doctrine ActiveRecord classes
 * based on a database schema.
 *
 * @package     Doctrine
 * @category    Object Relational Mapping
 * @link        www.phpdoctrine.com
 * @license     http://www.opensource.org/licenses/lgpl-license.php LGPL
 * @since       1.0
 * @version     $Revision$
 * @author      Konsta Vesterinen <kvesteri@cc.hut.fi>
 * @author      Jukka Hassinen <Jukka.Hassinen@BrainAlliance.com>
35
 * @author      Nicolas Bérard-Nault <nicobn@php.net>
lsmith's avatar
lsmith committed
36
 */
lsmith's avatar
lsmith committed
37 38
class Doctrine_Import_Builder
{
zYne's avatar
zYne committed
39 40 41
    /**
     * @var string $path    the path where imported files are being generated
     */
lsmith's avatar
lsmith committed
42 43 44 45 46 47
    private $path = '';

    private $suffix = '.php';

    private static $tpl;

lsmith's avatar
lsmith committed
48 49
    public function __construct()
    {
50
        $this->loadTemplate();
lsmith's avatar
lsmith committed
51 52 53
    }

    /**
zYne's avatar
zYne committed
54
     * setTargetPath
lsmith's avatar
lsmith committed
55
     *
zYne's avatar
zYne committed
56
     * @param string path   the path where imported files are being generated
lsmith's avatar
lsmith committed
57 58
     * @return
     */
lsmith's avatar
lsmith committed
59 60
    public function setTargetPath($path)
    {
lsmith's avatar
lsmith committed
61 62 63 64 65 66 67
        if ( ! file_exists($path)) {
            mkdir($path, 0777);
        }

        $this->path = $path;
    }
    /**
zYne's avatar
zYne committed
68
     * getTargetPath
lsmith's avatar
lsmith committed
69
     *
zYne's avatar
zYne committed
70
     * @return string       the path where imported files are being generated
lsmith's avatar
lsmith committed
71
     */
zYne's avatar
zYne committed
72
    public function getTargetPath()
lsmith's avatar
lsmith committed
73
    {
zYne's avatar
zYne committed
74
        return $this->path;
lsmith's avatar
lsmith committed
75 76
    }

77 78 79 80 81 82 83 84
    /**
     * This is a template that was previously in Builder/Record.tpl. Due to the fact
     * that it was not bundled when compiling, it had to be moved here.
     *
     * @access public
     * @return void
     */
    public function loadTemplate() 
lsmith's avatar
lsmith committed
85
    {
86 87
        if (isset(self::$tpl)) {
            return;
lsmith's avatar
lsmith committed
88
        }
89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111

        self::$tpl =<<<END
<?php
/**
 * This class has been auto-generated by the Doctrine ORM Framework
 * Created: %s
 */
class %s extends Doctrine_Record
{
    public function setTableDefinition()
    {
%s
    }
    public function setUp()
    {

    }
}
?>
END;

    }

112 113 114 115 116 117 118 119
    /*
     * Build the table definition of a Doctrine_Record object
     *
     * @param  string $table
     * @param  array  $tableColumns
     * @access public
     */
    public function buildDefinition($table, $tableColumns)
120 121 122
    {
        $columns   = array(0 => str_repeat(' ', 8) . '$this->setTableName(\'$table\');');
        $i = 1;
lsmith's avatar
lsmith committed
123

zYne's avatar
zYne committed
124 125
        foreach ($tableColumns as $name => $column) {
            $columns[$i] = '        $this->hasColumn(\'' . $name . '\', \'' . $column['ptype'][0] . '\'';
lsmith's avatar
lsmith committed
126 127 128 129 130 131 132 133
            if ($column['length']) {
                $columns[$i] .= ', ' . $column['length'];
            } else {
                $columns[$i] .= ', null';
            }

            $a = array();

zYne's avatar
zYne committed
134
            if (isset($column['default']) && $column['default']) {
lsmith's avatar
lsmith committed
135 136
                $a[] = '\'default\' => ' . var_export($column['default'], true);
            }
zYne's avatar
zYne committed
137
            if (isset($column['notnull']) && $column['notnull']) {
lsmith's avatar
lsmith committed
138 139
                $a[] = '\'notnull\' => true';
            }
zYne's avatar
zYne committed
140
            if (isset($column['primary']) && $column['primary']) {
lsmith's avatar
lsmith committed
141 142
                $a[] = '\'primary\' => true';
            }
zYne's avatar
zYne committed
143
            if (isset($column['autoinc']) && $column['autoinc']) {
lsmith's avatar
lsmith committed
144 145
                $a[] = '\'autoincrement\' => true';
            }
zYne's avatar
zYne committed
146
            if (isset($column['unique']) && $column['unique']) {
lsmith's avatar
lsmith committed
147 148
                $a[] = '\'unique\' => true';
            }
zYne's avatar
zYne committed
149
            if (isset($column['unsigned']) && $column['unsigned']) {
zYne's avatar
zYne committed
150 151
                $a[] = '\'unsigned\' => true';
            }
zYne's avatar
zYne committed
152 153 154
            if ($column['ptype'][0] == 'enum' && isset($column['values']) && $column['values']) {
                $a[] = '\'values\' => array(' . implode(',', $column['values']) . ')';
            }
lsmith's avatar
lsmith committed
155 156

            if ( ! empty($a)) {
zYne's avatar
zYne committed
157 158
                $columns[$i] .= ', ' . 'array(';
                $length = strlen($columns[$i]);
159
                $columns[$i] .= implode(',' . PHP_EOL . str_repeat(' ', $length), $a) . ')';
lsmith's avatar
lsmith committed
160 161 162 163
            }
            $columns[$i] .= ');';

            if ($i < (count($table) - 1)) {
164
                $columns[$i] .= PHP_EOL;
lsmith's avatar
lsmith committed
165 166 167
            }
            $i++;
        }
168 169 170
        
        return implode("\n", $columns);
    }
lsmith's avatar
lsmith committed
171

172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196
    public function buildRecord($table, $tableColumns, $className='', $fileName='')
    {
        if (empty($fileName)) {
            if (empty($this->path)) {
                $errMsg = 'No build target directory set.';
                throw new Doctrine_Import_Builder_Exception($errMsg);
            }
            

            if (is_writable($this->path) === false) {
                $errMsg = 'Build target directory ' . $this->path . ' is not writable.';
                throw new Doctrine_Import_Builder_Exception($errMsg);
            }

            $fileName  = $this->path . DIRECTORY_SEPARATOR . $className . $this->suffix;
        }
        
        $created   = date('l dS \of F Y h:i:s A');
        
        if (empty($className)) {
            $className = Doctrine::classify($table);
        }
        
        $content = sprintf(self::$tpl, $created, $className, 
                          $this->buildDefinition($table, $tableColumns));
lsmith's avatar
lsmith committed
197

zYne's avatar
zYne committed
198
        $bytes   = file_put_contents($fileName, $content);
lsmith's avatar
lsmith committed
199

zYne's avatar
zYne committed
200
        if ($bytes === false) {
lsmith's avatar
lsmith committed
201
            throw new Doctrine_Import_Builder_Exception("Couldn't write file " . $fileName);
zYne's avatar
zYne committed
202
        }
lsmith's avatar
lsmith committed
203
    }
204
    
lsmith's avatar
lsmith committed
205 206 207 208 209 210
    /**
     *
     * @param Doctrine_Schema_Object $schema
     * @throws Doctrine_Import_Exception
     * @return void
     */
lsmith's avatar
lsmith committed
211 212
    public function build(Doctrine_Schema_Object $schema)
    {
lsmith's avatar
lsmith committed
213 214 215 216 217 218 219 220
        foreach ($schema->getDatabases() as $database){
            foreach ($database->getTables() as $table){
                $this->buildRecord($table);
            }
        }
    }

}