December 2007


Somebody like to have one installation of cake core and many applications with it.

But  when you have many projects written in different time in diferent versions of cake this is impossible.

Appears problem how to easy use cake shells if you can’t add this util to path.

I propose next solution.

All we need is call modified script from app folder.

Example:

  cd /var/www/shop/app

  ./cake bake

Windows version cake.bat
@echo.
@echo off
@set path=%path%;C:\dev\_tools_\graphviz-2.16\bin\

SET app=%0
SET app1=%CD%
 
cd ..\cake\console
SET lib=%~dp0

php -q “%CD%\cake.php” -working “%app1%”  %*

echo.
cd %app1%
@echo on

Unix version: ./cake

#!/bin/bash
clear

APP=`pwd`
APP1=`pwd`
cd ../cake/console
LIB=${0/%cake/}

echo “Hello $USER,”

exec php -q ${LIB}cake.php -working “${APP1}” “$@”

cd ${APP1}
@echo on

echo ” “;

exit;

Advertisements

Simple task for build graphic representation of cake schema based on graphwiz.

For this task need to have installed graphviz in path or use “-tool path/to/graphwiz/dot”

Graphviz youcan dowload from  http://www.graphviz.org/Download..php 

 Live example was generated on well known aplication – Bakery. I also include bakery schema made in designer. For me generated graphviz schema looks more pretty and easier to explore.

Bakery DBDesigner schema.

Example of schema – bakery application

<?php/**
 * 
 * 
 * PHP versions 4 and 5
 *
 * Copyright (c) Tomenko Yevgeny
 *
 * Licensed under The MIT License
 * Redistributions of files must retain the above copyright notice.
 *
 */
uses(‘Folder’,‘File’,‘model’.DS.‘connection_manager’
);class VisualizeShell extends Shell {       var $DOC_DIR ;
    var 
$PREFIX
;
    var 
$graphToolPath ‘dot.exe’
;
// cake visualize -tool C:\dev\_tools_\graphviz-2.16\bin\dot.exe
    
function help
() {
        
$this->out(‘CakePHP visualise:’
);
        
$this->out(“cake visualise [-tool graphVizTool]”
);
        
$this->hr
();
    }
    function initialize() {
        
$this->DOC_DIR APP “doc”
;
        
$this->PREFIX“img_”
;
        if (isset(
$this->params[‘tool’
])) {
            
$this->graphToolPath =$this->params[‘tool’
];
        }
        return 
true
;
    }    
    function 
main
() { 
        
$this->help
();
        
$this->doVisualize
();    
    }
    
    function 
getSchemaInfo($modelName,$table_name
) {
        
$attrs 
= array();
        if (
App::import(‘model’,$modelName
)) {
            
$model = & new $modelName
();
            
$attrs=$model->schema
();
            return 
$attrs
;
        } else {
            
$DynamicModel = new Model(array(‘name’=> $modelName‘table’=> $table_name
)); 
            
$attrs=$DynamicModel->schema
();
            return 
$attrs
;
        }
        return 
false
;
    }     
    
    
    function 
doVisualize
() {
        
$header=$this->PREFIX+strftime(‘%Y-%m-%d %H:%M:%S’,time
());
        
$version=0
;
        if (
$version 0
) {
          
$header .= “\\nSchema version $version”
;
        }
        
$tableInfos 
= array();
        foreach(
$this->getAllTables() as $table_name
) {
            
$this->out(“Looking at table: {$table_name}”
);
            
$modelName=$this->_modelName($table_name
);
            
$tableInfos[$modelName] = $this->getSchemaInfo($modelName,$table_name
);
        }
        if (!file_exists($this->DOC_DIR) || !is_dir($this->DOC_DIR)) {
            
$this->out(“Creating directory \”{$this->DOC_DIR}\”…”
);
            
$folder = & new Folder($this->DOC_DIRtrue
);
        }
        
$this->writeDotFile($header$this->DOC_DIR$tableInfos
);
    }       function 
getAllTables($useDbConfig ‘default’
) {
        
$db =& ConnectionManager::getDataSource($useDbConfig
);
        
$usePrefix = empty($db->config[‘prefix’]) ? ” $db->config[‘prefix’
];
        if (
$usePrefix
) {
            
$tables 
= array();
            foreach (
$db->listSources() as $table
) {
                if (!
strncmp($table$usePrefixstrlen($usePrefix
))) {
                    
$tables[] = substr($tablestrlen($usePrefix
));
                }
            }
        } else {
            
$tables $db->listSources
();
        }
        
$this->__tables $tables
;
        return 
$tables
;
    }
    function writeDotFile($header$target_dir$tableInfos) {
        
$tmp_dot_file $target_dir .DS“model_information.dot”
;        $f = & new File($tmp_dot_filetrue
);
        
        
// Define a graph and some global settings
        
$f->append(“digraph G {\n”
);
        
$f->append(“\toverlap=false;\n”
);
        
$f->append(“\tsplines=true;\n”
);
        
$f->append(“\tnode [fontname=\”Helvetica\”,fontsize=9];\n”
);
        
$f->append(“\tedge [fontname=\”Helvetica\”,fontsize=8];\n”
);
        
$f->append(“\tranksep=0.1;\n”
);
        
$f->append(“\tnodesep=0.1;\n”
);
//    $f->append(“\tedge [decorate=\”true\”];\n”);        // Write header info
        $f->append(“\t_schema_info [shape=\”plaintext\”, label=\”{$header}\”, fontname=\”Helvetica\”,fontsize=8];\n”);
        
        
$assocs 
= array();
        
// Draw the tables as boxes
        
foreach ($tableInfos as $table=>$attributes
) {
          
$attrs “”
;
          if (
is_array($attributes) && count($attributes)>0
) {
              foreach (
$attributes as $attrname=>$attr
) {
                if (
substr($attrname, –3) == ‘_id’
) { 
                  
# Create an association to other table
                  
$table_name Inflector::camelize(r(‘_id’,,$attrname
));
                  if (!empty(
$tableInfos[$table_name
])) {
                    
$other_table $tableInfos[$table_name
];
                    
$assocs[] = array(‘label’=> $attrname‘node1’=> $table‘node2’=> $table_name
);
                  }
                }
                if (!empty(
$attr[‘length’])) $attr[‘type’].=“[{$attr[‘length’]}]”
;
                
$attrtype=$attr[‘type’
];
                
$attrs .= “{$attrname} : {$attrtype}”
;
                if (!empty(
$attr[‘default’])) $attrs .= “, default: \\\”{$attr[‘default’]}\\\””
;
                
$attrs .= “\\n”
;
              }
          }
          
$f->append(“\t\”{$table}\” [label=\”{{$table}|{$attrs}}\” shape=\”record\”];\n”
);
        }
        
// Draw the relations
        
foreach ($assocs as $assoc
) {
          
$f->append(“\t\”{$assoc[‘node1’]}\” -> \”{$assoc[‘node2’]}\” [label=\”{$assoc[‘label’]}\”]\n”
);
        }
        
        
// Close the graph
        
$f->append(“}\n”
);
        
$f->close
();        
// Create the images by using dot and neato (grapviz tools)
        // We’ll create several images with different layout. There is no “prefect” layout algorithm that suits all models
        
$this->createImg($this->graphToolPath“-Gmode=hier”$tmp_dot_file$target_dir .DS“model_overview_neato_hier”
);
        
$this->createImg($this->graphToolPath“”$tmp_dot_file$target_dirDS“model_overview_neato_plain”
);
        
        
// Remove the .dot file
        
$f->delete
();
        
    }     
  
    function 
createImg($app$args$dot_file$img_file_base
) {        
        
$img_file “$img_file_base.png”
;
        
$command “{$app} {$args} -Tpng  -o\”{$img_file}\” \”{$dot_file}\””
;
        
system($command,$retval
);
        if (!
$retval
) {
            
$this->out(“Generated {$img_file}\n”
);
        } else {
            
$this->out(“Failed to execute the ‘{$app}’ command! Is grapviz (www.graphviz.org) installed?\n”
);          
        }
    }     
    
    
 
    
}
?>