1 <?php
2 3 4 5 6 7 8 9 10
11 class ModelViewer extends Controller {
12 static $url_handlers = array(
13 '$Module!' => 'handleModule',
14 );
15
16 protected $module = null;
17
18 function handleModule($request) {
19 return new ModelViewer_Module($request->param('Module'));
20 }
21
22 function init() {
23 parent::init();
24
25 $canAccess = (Director::isDev() || Director::is_cli() || Permission::check("ADMIN"));
26 if(!$canAccess) return Security::permissionFailure($this);
27
28
29 $returnCode = 0;
30 $output = array();
31 exec("which neato", $output, $returnCode);
32 if($returnCode != 0) {
33 user_error(
34 'You don\'t seem to have the GraphViz library (http://graphviz.org/) and the "neato" command-line utility available',
35 E_USER_ERROR
36 );
37 }
38 }
39
40 41 42
43 function Models() {
44 $classes = ClassInfo::subclassesFor('DataObject');
45 array_shift($classes);
46 $output = new DataObjectSet();
47 foreach($classes as $class) {
48 $output->push(new ModelViewer_Model($class));
49 }
50 return $output;
51 }
52
53 54 55
56 function Modules() {
57 $classes = ClassInfo::subclassesFor('DataObject');
58 array_shift($classes);
59
60 $modules = array();
61 foreach($classes as $class) {
62 $model = new ModelViewer_Model($class);
63 if(!isset($modules[$model->Module])) $modules[$model->Module] = new DataObjectSet();
64 $modules[$model->Module]->push($model);
65 }
66 ksort($modules);
67 unset($modules['userforms']);
68
69 if($this->module) {
70 $modules = array($this->module => $modules[$this->module]);
71 }
72
73 $output = new DataObjectSet();
74 foreach($modules as $moduleName => $models) {
75 $output->push(new ArrayData(array(
76 'Link' => 'dev/viewmodel/' . $moduleName,
77 'Name' => $moduleName,
78 'Models' => $models,
79 )));
80 }
81
82 return $output;
83 }
84 }
85
86 87 88 89
90 class ModelViewer_Module extends ModelViewer {
91 static $url_handlers = array(
92 'graph' => 'graph',
93 );
94
95 96 97
98 function __construct($module = null) {
99 $this->module = $module;
100
101 parent::__construct();
102 }
103
104 function graph() {
105 SSViewer::set_source_file_comments(false);
106 $dotContent = $this->renderWith("ModelViewer_dotsrc");
107 $CLI_dotContent = escapeshellarg($dotContent);
108
109 $output= `echo $CLI_dotContent | neato -Tpng:gd &> /dev/stdout`;
110 if(substr($output,1,3) == 'PNG') header("Content-type: image/png");
111 else header("Content-type: text/plain");
112 echo $output;
113 }
114 }
115
116 117 118 119 120 121
122 class ModelViewer_Model extends ViewableData {
123 protected $className;
124
125 function __construct($className) {
126 $this->className = $className;
127 parent::__construct();
128 }
129
130 function getModule() {
131 global $_CLASS_MANIFEST;
132 $className = $this->className;
133 if(($pos = strpos($className,'_')) !== false) $className = substr($className,0,$pos);
134 if(isset($_CLASS_MANIFEST[$className])) {
135 if(preg_match('/^'.str_replace('/','\/',preg_quote(BASE_PATH)).'\/([^\/]+)\//', $_CLASS_MANIFEST[$className], $matches)) {
136 return $matches[1];
137 }
138 }
139 }
140
141 function getName() {
142 return $this->className;
143 }
144
145 function getParentModel() {
146 $parentClass = get_parent_class($this->className);
147 if($parentClass != "DataObject") return $parentClass;
148 }
149
150 function Fields() {
151 $output = new DataObjectSet();
152
153 $output->push(new ModelViewer_Field($this,'ID', 'PrimaryKey'));
154 if(!$this->ParentModel) {
155 $output->push(new ModelViewer_Field($this,'Created', 'Datetime'));
156 $output->push(new ModelViewer_Field($this,'LastEdited', 'Datetime'));
157 }
158
159 $db = singleton($this->className)->uninherited('db',true);
160 if($db) foreach($db as $k => $v) {
161 $output->push(new ModelViewer_Field($this, $k, $v));
162 }
163 return $output;
164 }
165
166 function Relations() {
167 $output = new DataObjectSet();
168
169 foreach(array('has_one','has_many','many_many') as $relType) {
170 $items = singleton($this->className)->uninherited($relType,true);
171 if($items) foreach($items as $k => $v) {
172 $output->push(new ModelViewer_Relation($this, $k, $v, $relType));
173 }
174 }
175 return $output;
176 }
177 }
178
179 180 181 182
183 class ModelViewer_Field extends ViewableData {
184 public $Model, $Name, $Type;
185
186 function __construct($model, $name, $type) {
187 $this->Model = $model;
188 $this->Name = $name;
189 $this->Type = $type;
190
191 parent::__construct();
192 }
193 }
194
195 196 197 198
199 class ModelViewer_Relation extends ViewableData {
200 public $Model, $Name, $RelationType, $RelatedClass;
201
202 function __construct($model, $name, $relatedClass, $relationType) {
203 $this->Model = $model;
204 $this->Name = $name;
205 $this->RelatedClass = $relatedClass;
206 $this->RelationType = $relationType;
207
208 parent::__construct();
209 }
210
211 }
212
213 ?>
[Raise a SilverStripe Framework issue/bug](https://github.com/silverstripe/silverstripe-framework/issues/new)
- [Raise a SilverStripe CMS issue/bug](https://github.com/silverstripe/silverstripe-cms/issues/new)
- Please use the
Silverstripe Forums to ask development related questions.
-