Skip to content

Instantly share code, notes, and snippets.

@ravage84
Last active December 28, 2015 18:48
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save ravage84/7545337 to your computer and use it in GitHub Desktop.
Save ravage84/7545337 to your computer and use it in GitHub Desktop.
Inspired by a question on the CakePHP Community page on Facebook (https://www.facebook.com/groups/cake.community/permalink/673205099378177/), I created a really quick and dirty solution using ReflectionClass, the dot language, which is used by GraphViz and the online tool http://www.webgraphviz.com/
<?php
App::uses('AppController', 'Controller');
class ModelRelationVizController extends AppController {
public $uses = array();
public function beforeFilter() {
if (Configure::read('debug') < 1) {
throw new MethodNotAllowedException(__('Debug setting does not allow access to this url.'));
}
parent::beforeFilter();
}
public function index() {
$modelPath = ROOT . DS . APP_DIR . DS . 'Model';
$skipModels = array('AppModel');
$modelRelationArray = array();
$skippedClassCount = 0;
$hasOneCount = 0;
$hasManyCount = 0;
$belongsToCount = 0;
$hasAndBelongsToManyCount = 0;
$relationCount = 0;
$skippedRelationCount = 0;
$relationTypes = array(
'hasOne',
'hasMany',
'belongsTo',
'hasAndBelongsToMany',
);
$modelFiles = glob($modelPath . '/*.php', GLOB_NOSORT);
$classCount = count($modelFiles);
foreach ($modelFiles as $modelFile) {
$modelClass = basename($modelFile, '.php');
if (in_array($modelClass, $skipModels)) {
$skippedClassCount++;
continue;
}
require_once $modelFile;
$reflectionClass = new ReflectionClass($modelClass);
$modelRelationArray[$modelClass] = array();
foreach ($relationTypes as $relationType) {
if ($reflectionClass->hasProperty($relationType)) {
$modelRelations = $reflectionClass->getProperty($relationType)->getValue(new $modelClass);
foreach ($modelRelations as $relationAlias => $modelRelation) {
$relationCount++;
if (in_array($modelRelation['className'], $skipModels)) {
$skippedRelationCount++;
continue;
}
${$relationType . 'Count'} += 1;
$modelRelationArray[$modelClass][$relationType][$relationAlias] = $modelRelation;
}
}
}
}
$this->set('classCount', $classCount);
$this->set('skippedClassCount', $skippedClassCount);
$this->set('hasOneCount', $hasOneCount);
$this->set('hasManyCount', $hasManyCount);
$this->set('belongsToCount', $belongsToCount);
$this->set('hasAndBelongsToManyCount', $hasAndBelongsToManyCount);
$this->set('relationCount', $relationCount);
$this->set('skippedRelationCount', $skippedRelationCount);
$this->set('modelRelationArray', $modelRelationArray);
}
}
<?php ?>
<h1>ModelRelationViz</h1>
<h2>Statistics</h2>
<table>
<tbody>
<tr>
<th style='text-align: left;'><?php echo __('Total classes found:'); ?></th>
<td><?php echo h($classCount); ?></td>
</tr>
<tr>
<th style='text-align: left;'><?php echo __('Classes skipped'); ?></th>
<td><?php echo h($skippedClassCount); ?></td>
</tr>
<tr>
<th style='text-align: left;'><?php echo __('hasOne relations found:'); ?></th>
<td><?php echo h($hasOneCount); ?></td>
</tr>
<tr>
<th style='text-align: left;'><?php echo __('hasMany relations found:'); ?></th>
<td><?php echo h($hasManyCount); ?></td>
</tr>
<tr>
<th style='text-align: left;'><?php echo __('belongsTo relations found:'); ?></th>
<td><?php echo h($belongsToCount); ?></td>
</tr>
<tr>
<th style='text-align: left;'><?php echo __('hasAndBelongsToMany relations found:'); ?></th>
<td><?php echo h($hasAndBelongsToManyCount); ?></td>
</tr>
<tr>
<th style='text-align: left;'><?php echo __('Total relations found:'); ?></th>
<td><?php echo h($relationCount); ?></td>
</tr>
<tr>
<th style='text-align: left;'><?php echo __('Relations skipped'); ?></th>
<td><?php echo h($skippedRelationCount); ?></td>
</tr>
</tbody>
</table>
<h2>GraphViz Data</h2>
<pre>
digraph prof {
ratio = fill;
node [style=filled];
<?php foreach ($modelRelationArray as $modelClassName => $modelRelationTypes):
$rColor = mt_rand(100, 900) / 1000;
$gColor = mt_rand(100, 900) / 1000;
$bColor = mt_rand(100, 900) / 1000;
echo sprintf('%s [color="%s %s %s"]' . PHP_EOL, $modelClassName, $rColor, $gColor, $bColor);
foreach($modelRelationTypes as $modelRelationTypeName => $modelRelations):
foreach ($modelRelations as $relationAlias => $modelRelation):
echo sprintf('%s -> %s [color="%s %s %s", label = "%s as %s"]' . PHP_EOL,
$modelClassName,
$modelRelation['className'],
$rColor,
$gColor,
$bColor,
$modelRelationTypeName,
$relationAlias
);
endforeach;
endforeach;
endforeach; ?>
}
</pre>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment