From e262a291933636b32b5133e28ceb0f01c7ba85b6 Mon Sep 17 00:00:00 2001
From: Mateusz Uzdowski
Date: Tue, 17 Apr 2012 14:45:26 +1200
Subject: [PATCH 1/2] ENHANCEMENT: move code introspection functions to the
silverstripe-codeviz module
---
css/CodeViewer.css | 3 -
css/TestViewer.css | 3 -
dev/CodeViewer.php | 351 --------------------------------
dev/DevelopmentAdmin.php | 11 +-
dev/ModelViewer.php | 213 -------------------
dev/TestViewer.php | 257 -----------------------
scss/CodeViewer.scss | 14 --
scss/TestViewer.scss | 14 --
templates/CodeViewer.ss | 9 -
templates/ModelViewer.ss | 34 ----
templates/ModelViewer_dotsrc.ss | 20 --
templates/TestViewer.ss | 9 -
12 files changed, 1 insertion(+), 937 deletions(-)
delete mode 100644 css/CodeViewer.css
delete mode 100644 css/TestViewer.css
delete mode 100644 dev/CodeViewer.php
delete mode 100644 dev/ModelViewer.php
delete mode 100644 dev/TestViewer.php
delete mode 100755 scss/CodeViewer.scss
delete mode 100755 scss/TestViewer.scss
delete mode 100644 templates/CodeViewer.ss
delete mode 100644 templates/ModelViewer.ss
delete mode 100644 templates/ModelViewer_dotsrc.ss
delete mode 100644 templates/TestViewer.ss
diff --git a/css/CodeViewer.css b/css/CodeViewer.css
deleted file mode 100644
index 2cd9f3493..000000000
--- a/css/CodeViewer.css
+++ /dev/null
@@ -1,3 +0,0 @@
-pre { border: 1px #777 solid; background-color: #CCC; color: #333; margin: 0.5em 2em; padding: 1em; line-height: 120%; }
-
-pre strong { background-color: #FFC; color: #000; padding: 2px; }
diff --git a/css/TestViewer.css b/css/TestViewer.css
deleted file mode 100644
index 2cd9f3493..000000000
--- a/css/TestViewer.css
+++ /dev/null
@@ -1,3 +0,0 @@
-pre { border: 1px #777 solid; background-color: #CCC; color: #333; margin: 0.5em 2em; padding: 1em; line-height: 120%; }
-
-pre strong { background-color: #FFC; color: #000; padding: 2px; }
diff --git a/dev/CodeViewer.php b/dev/CodeViewer.php
deleted file mode 100644
index a2546da35..000000000
--- a/dev/CodeViewer.php
+++ /dev/null
@@ -1,351 +0,0 @@
- 'browse',
- '$Class' => 'viewClass'
- );
-
- static $allowed_actions = array(
- 'index',
- 'browse',
- 'viewClass'
- );
-
- /**
- * Define a simple finite state machine.
- * Top keys are the state names. 'start' is the first state, and 'die' is the error state.
- * Inner keys are token names/codes. The values are either a string, new state, or an array(new state, handler method).
- * The handler method will be passed the PHP token as an argument, and is expected to populate a property of the object.
- */
- static $fsm = array(
- 'start' => array(
- T_CLASS => array('className','createClass'),
- T_DOC_COMMENT => array('', 'saveClassComment'),
- ),
- 'className' => array(
- T_STRING => array('classSpec', 'setClassName'),
- ),
- 'classSpec' => array(
- '{' => 'classBody',
- ),
- 'classBody' => array(
- T_FUNCTION => array('methodName','createBodyMethod'),
- '}' => array('start', 'completeClass'),
- T_DOC_COMMENT => array('', 'saveMethodComment'),
- ),
- 'methodName' => array(
- T_STRING => array('methodSpec', 'setMethodName'),
- ),
- 'methodSpec' => array(
- '{' => 'methodBody',
- ),
- 'methodBody' => array(
- '{' => array('!push','appendMethodContent'),
- '}' => array(
- 'hasstack' => array('!pop', 'appendMethodContent'),
- 'nostack' => array('classBody', 'completeMethod'),
- ),
- T_VARIABLE => array('variable', 'potentialMethodCall'),
- T_COMMENT => array('', 'appendMethodComment'),
- T_DOC_COMMENT => array('', 'appendMethodComment'),
- '*' => array('', 'appendMethodContent'),
- ),
- 'variable' => array(
- T_OBJECT_OPERATOR => array('variableArrow', 'potentialMethodCall'),
- '*' => array('methodBody', 'appendMethodContent'),
- ),
- 'variableArrow' => array(
- T_STRING => array('methodOrProperty', 'potentialMethodCall'),
- T_WHITESPACE => array('', 'potentialMethodCall'),
- '*' => array('methodBody', 'appendMethodContent'),
- ),
- 'methodOrProperty' => array(
- '(' => array('methodCall', 'potentialMethodCall'),
- T_WHITESPACE => array('', 'potentialMethodCall'),
- '*' => array('methodBody', 'appendMethodContent'),
- ),
- 'methodCall' => array(
- '(' => array('!push/nestedInMethodCall', 'potentialMethodCall'),
- ')' => array('methodBody', 'completeMethodCall'),
- '*' => array('', 'potentialMethodCall'),
- ),
- 'nestedInMethodCall' => array(
- '(' => array('!push', 'potentialMethodCall'),
- ')' => array('!pop', 'potentialMethodCall'),
- '*' => array('', 'potentialMethodCall'),
- ),
- );
-
- function init() {
- parent::init();
-
- if(!Permission::check('ADMIN')) return Security::permissionFailure();
- TestRunner::use_test_manifest();
- }
-
- public function browse() {
- $classes = ClassInfo::subclassesFor('SapphireTest');
-
- array_shift($classes);
- ksort($classes);
-
- $result ='View any of the following test classes ';
- $result .='';
-
- $result .='View any of the following other classes ';
-
- $classes = array_keys(ClassInfo::allClasses());
- sort($classes);
-
- $result .='';
-
- return $this->customise(array (
- 'Content' => $result
- ))->renderWith('CodeViewer');
- }
-
- public function viewClass(SS_HTTPRequest $request) {
- $class = $request->param('Class');
-
- if(!class_exists($class)) {
- throw new Exception('CodeViewer->viewClass(): not passed a valid class to view (does the class exist?)');
- }
-
- return $this->customise(array (
- 'Content' => $this->testAnalysis(getClassFile($class))
- ))->renderWith('CodeViewer');
- }
-
- public function Link($action = null) {
- return Controller::join_links(Director::absoluteBaseURL(), 'dev/viewcode/', $action);
- }
-
- protected $classComment, $methodComment;
-
- function saveClassComment($token) {
- $this->classComment = $this->parseComment($token);
- }
- function saveMethodComment($token) {
- $this->methodComment = $this->parseComment($token);
- }
-
- function createClass($token) {
- $this->currentClass = array(
- "description" => $this->classComment['pretty'],
- "heading" => isset($this->classComment['heading']) ? $this->classComment['heading'] : null,
- );
- $ths->classComment = null;
- }
- function setClassName($token) {
- $this->currentClass['name'] = $token[1];
- if(!$this->currentClass['heading']) $this->currentClass['heading'] = $token[1];
- }
- function completeClass($token) {
- $this->classes[] = $this->currentClass;
- }
-
- function createBodyMethod($token) {
- $this->currentMethod = array();
- $this->currentMethod['content'] = "";
- $this->currentMethod['description'] = $this->methodComment['pretty'];
- $this->currentMethod['heading'] = isset($this->methodComment['heading']) ? $this->methodComment['heading'] : null;
- $this->methodComment = null;
-
- }
- function setMethodName($token) {
- $this->currentMethod['name'] = $token[1];
- if(!$this->currentMethod['heading']) $this->currentMethod['heading'] = $token[1];
- }
- function appendMethodComment($token) {
- if(substr($token[1],0,2) == '/*') {
- $this->closeOffMethodContentPre();
- $this->currentMethod['content'] .= $this->prettyComment($token) . "";
- } else {
- $this->currentMethod['content'] .= $this->renderToken($token);
- }
- }
-
- function prettyComment($token) {
- $comment = preg_replace('/^\/\*/','',$token[1]);
- $comment = preg_replace('/\*\/$/','',$comment);
- $comment = preg_replace('/(^|\n)[\t ]*\* */m',"\n",$comment);
- $comment = htmlentities($comment, ENT_COMPAT, 'UTF-8');
- $comment = str_replace("\n\n", "
", $comment);
- return "
$comment
";
- }
-
- function parseComment($token) {
- $parsed = array();
-
- $comment = preg_replace('/^\/\*/','',$token[1]);
- $comment = preg_replace('/\*\/$/','',$comment);
- $comment = preg_replace('/(^|\n)[\t ]*\* */m',"\n",$comment);
-
- foreach(array('heading','nav') as $var) {
- if(preg_match('/@' . $var . '\s+([^\n]+)\n/', $comment, $matches)) {
- $parsed[$var] = $matches[1];
- $comment = preg_replace('/@' . $var . '\s+([^\n]+)\n/','', $comment);
- }
- }
-
- $parsed['pretty'] = "" . str_replace("\n\n", "
", htmlentities($comment, ENT_COMPAT, 'UTF-8')). "
";
- return $parsed;
- }
-
- protected $isNewLine = true;
-
- function appendMethodContent($token) {
- if($this->potentialMethodCall) {
- $this->currentMethod['content'] .= $this->potentialMethodCall;
- $this->potentialMethodCall = "";
- }
- //if($this->isNewLine && isset($token[2])) $this->currentMethod['content'] .= $token[2] . ": ";
- $this->isNewLine = false;
- $this->currentMethod['content'] .= $this->renderToken($token);
- }
- function completeMethod($token) {
- $this->closeOffMethodContentPre();
- $this->currentMethod['content'] = str_replace("\n\t\t","\n",$this->currentMethod['content']);
- $this->currentClass['methods'][] = $this->currentMethod;
- }
-
- protected $potentialMethodCall = "";
- function potentialMethodCall($token) {
- $this->potentialMethodCall .= $this->renderToken($token);
- }
- function completeMethodCall($token) {
- $this->potentialMethodCall .= $this->renderToken($token);
- if(strpos($this->potentialMethodCall, '->assert') !== false) {
- $this->currentMethod['content'] .= "" . $this->potentialMethodCall . " ";
- } else {
- $this->currentMethod['content'] .= $this->potentialMethodCall;
- }
- $this->potentialMethodCall = "";
- }
-
- /**
- * Finish the "pre" block in method content.
- * Will remove whitespace and empty "pre" blocks
- */
- function closeOffMethodContentPre() {
- $this->currentMethod['content'] = trim($this->currentMethod['content']);
- if(substr($this->currentMethod['content'],-5) == '') $this->currentMethod['content'] = substr($this->currentMethod['content'], 0,-5);
- else $this->currentMethod['content'] .= ' ';
- }
-
- /**
- * Render the given token as HTML
- */
- function renderToken($token) {
- $tokenContent = htmlentities(
- is_array($token) ? $token[1] : $token,
- ENT_COMPAT,
- 'UTF-8'
- );
- $tokenName = is_array($token) ? token_name($token[0]) : 'T_PUNCTUATION';
-
- switch($tokenName) {
- case "T_WHITESPACE":
- if(strpos($tokenContent, "\n") !== false) $this->isNewLine = true;
- return $tokenContent;
- default:
- return "$tokenContent ";
- }
- }
-
- protected $classes = array();
- protected $currentMethod, $currentClass;
-
- function testAnalysis($file) {
- $content = file_get_contents($file);
- $tokens = token_get_all($content);
-
- // Execute a finite-state-machine with a built-in state stack
- // This FSM+stack gives us enough expressive power for simple PHP parsing
- $state = "start";
- $stateStack = array();
-
- //echo "state $state";
- foreach($tokens as $token) {
- // Get token name - some tokens are arrays, some arent'
- if(is_array($token)) $tokenName = $token[0]; else $tokenName = $token;
- //echo " token '$tokenName'";
-
- // Find the rule for that token in the current state
- if(isset(self::$fsm[$state][$tokenName])) $rule = self::$fsm[$state][$tokenName];
- else if(isset(self::$fsm[$state]['*'])) $rule = self::$fsm[$state]['*'];
- else $rule = null;
-
- // Check to see if we have specified multiple rules depending on whether the stack is populated
- if(is_array($rule) && array_keys($rule) == array('hasstack', 'nostack')) {
- if($stateStack) $rule = $rule['hasstack'];
- else $rule = $rule = $rule['nostack'];
- }
-
- if(is_array($rule)) {
- list($destState, $methodName) = $rule;
- $this->$methodName($token);
- } else if($rule) {
- $destState = $rule;
- } else {
- $destState = null;
- }
- //echo " ->state $destState";
-
- if(preg_match('/!(push|pop)(\/[a-zA-Z0-9]+)?/', $destState, $parts)) {
- $action = $parts[1];
- $argument = isset($parts[2]) ? substr($parts[2],1) : null;
- $destState = null;
-
- switch($action) {
- case "push":
- $stateStack[] = $state;
- if($argument) $destState = $argument;
- break;
-
- case "pop":
- if($stateStack) $destState = array_pop($stateStack);
- else if($argument) $destState = $argument;
- else user_error("State transition '!pop' was attempted with an empty state-stack and no default option specified.", E_USER_ERROR);
- }
- }
-
- if($destState) $state = $destState;
- if(!isset(self::$fsm[$state])) user_error("Transition to unrecognised state '$state'", E_USER_ERROR);
- }
-
- $subclasses = ClassInfo::subclassesFor('SapphireTest');
- foreach($this->classes as $classDef) {
- if(true ||in_array($classDef['name'], $subclasses)) {
- echo "$classDef[heading] ";
- echo "$classDef[description]
";
- if(isset($classDef['methods'])) foreach($classDef['methods'] as $method) {
- if(true || substr($method['name'],0,4) == 'test') {
- //$title = ucfirst(strtolower(preg_replace('/([a-z])([A-Z])/', '$1 $2', substr($method['name'], 4))));
- $title = $method['heading'];
-
- echo "$title ";
- echo "$method[description]
";
- echo $method['content'];
- }
- }
- }
-
- }
- }
-}
diff --git a/dev/DevelopmentAdmin.php b/dev/DevelopmentAdmin.php
index 5e43a0e62..eecb54dda 100644
--- a/dev/DevelopmentAdmin.php
+++ b/dev/DevelopmentAdmin.php
@@ -83,8 +83,7 @@ class DevelopmentAdmin extends Controller {
"tests/endsession" => "Ends a test session",
"jstests" => "See a list of JavaScript tests to run",
"jstests/all" => "Run all JavaScript tests",
- "tasks" => "See a list of build tasks to run",
- "viewcode" => "Read source code in a literate programming style",
+ "tasks" => "See a list of build tasks to run"
);
// Web mode
@@ -127,10 +126,6 @@ class DevelopmentAdmin extends Controller {
return TaskRunner::create();
}
- function viewmodel() {
- return ModelViewer::create();
- }
-
function build($request) {
if(Director::is_cli()) {
$da = DatabaseAdmin::create();
@@ -187,8 +182,4 @@ class DevelopmentAdmin extends Controller {
function errors() {
Director::redirect("Debug_");
}
-
- function viewcode($request) {
- return CodeViewer::create();
- }
}
diff --git a/dev/ModelViewer.php b/dev/ModelViewer.php
deleted file mode 100644
index c385adb53..000000000
--- a/dev/ModelViewer.php
+++ /dev/null
@@ -1,213 +0,0 @@
- 'handleModule',
- );
-
- protected $module = null;
-
- function handleModule($request) {
- return new ModelViewer_Module($request->param('Module'));
- }
-
- function init() {
- parent::init();
-
- $canAccess = (Director::isDev() || Director::is_cli() || Permission::check("ADMIN"));
- if(!$canAccess) return Security::permissionFailure($this);
-
- // check for graphviz dependencies
- $returnCode = 0;
- $output = array();
- exec("which neato", $output, $returnCode);
- if($returnCode != 0) {
- user_error(
- 'You don\'t seem to have the GraphViz library (http://graphviz.org/) and the "neato" command-line utility available',
- E_USER_ERROR
- );
- }
- }
-
- /**
- * Model classes
- */
- function Models() {
- $classes = ClassInfo::subclassesFor('DataObject');
- array_shift($classes);
- $output = new ArrayList();
- foreach($classes as $class) {
- $output->push(new ModelViewer_Model($class));
- }
- return $output;
- }
-
- /**
- * Model classes, grouped by Module
- */
- function Modules() {
- $classes = ClassInfo::subclassesFor('DataObject');
- array_shift($classes);
-
- $modules = array();
- foreach($classes as $class) {
- $model = new ModelViewer_Model($class);
- if(!isset($modules[$model->Module])) $modules[$model->Module] = new ArrayList();
- $modules[$model->Module]->push($model);
- }
- ksort($modules);
- unset($modules['userforms']);
-
- if($this->module) {
- $modules = array($this->module => $modules[$this->module]);
- }
-
- $output = new ArrayList();
- foreach($modules as $moduleName => $models) {
- $output->push(new ArrayData(array(
- 'Link' => 'dev/viewmodel/' . $moduleName,
- 'Name' => $moduleName,
- 'Models' => $models,
- )));
- }
-
- return $output;
- }
-}
-
-/**
- * @package framework
- * @subpackage tools
- */
-class ModelViewer_Module extends ModelViewer {
- static $url_handlers = array(
- 'graph' => 'graph',
- );
-
- /**
- * ModelViewer can be optionally constructed to restrict its output to a specific module
- */
- function __construct($module = null) {
- $this->module = $module;
-
- parent::__construct();
- }
-
- function graph() {
- SSViewer::set_source_file_comments(false);
- $dotContent = $this->renderWith("ModelViewer_dotsrc");
- $CLI_dotContent = escapeshellarg($dotContent);
-
- $output= `echo $CLI_dotContent | neato -Tpng:gd &> /dev/stdout`;
- if(substr($output,1,3) == 'PNG') header("Content-type: image/png");
- else header("Content-type: text/plain");
- echo $output;
- }
-}
-
-/**
- * Represents a single model in the model viewer
- *
- * @package framework
- * @subpackage tools
- */
-class ModelViewer_Model extends ViewableData {
- protected $className;
-
- function __construct($className) {
- $this->className = $className;
- parent::__construct();
- }
-
- function getModule() {
- $classes = SS_ClassLoader::instance()->getManifest()->getClasses();
- $className = strtolower($this->className);
-
- if(($pos = strpos($className,'_')) !== false) $className = substr($className,0,$pos);
- if(isset($classes[$className])) {
- if(preg_match('/^'.str_replace('/','\/',preg_quote(BASE_PATH)).'\/([^\/]+)\//', $classes[$className], $matches)) {
- return $matches[1];
- }
- }
- }
-
- function getName() {
- return $this->className;
- }
-
- function getParentModel() {
- $parentClass = get_parent_class($this->className);
- if($parentClass != "DataObject") return $parentClass;
- }
-
- function Fields() {
- $output = new ArrayList();
-
- $output->push(new ModelViewer_Field($this,'ID', 'PrimaryKey'));
- if(!$this->ParentModel) {
- $output->push(new ModelViewer_Field($this,'Created', 'Datetime'));
- $output->push(new ModelViewer_Field($this,'LastEdited', 'Datetime'));
- }
-
- $db = singleton($this->className)->uninherited('db',true);
- if($db) foreach($db as $k => $v) {
- $output->push(new ModelViewer_Field($this, $k, $v));
- }
- return $output;
- }
-
- function Relations() {
- $output = new ArrayList();
-
- foreach(array('has_one','has_many','many_many') as $relType) {
- $items = singleton($this->className)->uninherited($relType,true);
- if($items) foreach($items as $k => $v) {
- $output->push(new ModelViewer_Relation($this, $k, $v, $relType));
- }
- }
- return $output;
- }
-}
-
-/**
- * @package framework
- * @subpackage tools
- */
-class ModelViewer_Field extends ViewableData {
- public $Model, $Name, $Type;
-
- function __construct($model, $name, $type) {
- $this->Model = $model;
- $this->Name = $name;
- $this->Type = $type;
-
- parent::__construct();
- }
-}
-
-/**
- * @package framework
- * @subpackage tools
- */
-class ModelViewer_Relation extends ViewableData {
- public $Model, $Name, $RelationType, $RelatedClass;
-
- function __construct($model, $name, $relatedClass, $relationType) {
- $this->Model = $model;
- $this->Name = $name;
- $this->RelatedClass = $relatedClass;
- $this->RelationType = $relationType;
-
- parent::__construct();
- }
-
-}
-
diff --git a/dev/TestViewer.php b/dev/TestViewer.php
deleted file mode 100644
index 7792b0ab0..000000000
--- a/dev/TestViewer.php
+++ /dev/null
@@ -1,257 +0,0 @@
- array(
- T_CLASS => array('className','createClass'),
- ),
- 'className' => array(
- T_STRING => array('classSpec', 'setClassName'),
- ),
- 'classSpec' => array(
- '{' => 'classBody',
- ),
- 'classBody' => array(
- T_FUNCTION => array('methodName','createBodyMethod'),
- '}' => array('start', 'completeClass'),
- ),
- 'methodName' => array(
- T_STRING => array('methodSpec', 'setMethodName'),
- ),
- 'methodSpec' => array(
- '{' => 'methodBody',
- ),
- 'methodBody' => array(
- '{' => array('!push','appendMethodContent'),
- '}' => array(
- 'hasstack' => array('!pop', 'appendMethodContent'),
- 'nostack' => array('classBody', 'completeMethod'),
- ),
- T_VARIABLE => array('variable', 'potentialMethodCall'),
- T_COMMENT => array('', 'appendMethodComment'),
- '*' => array('', 'appendMethodContent'),
- ),
- 'variable' => array(
- T_OBJECT_OPERATOR => array('variableArrow', 'potentialMethodCall'),
- '*' => array('methodBody', 'appendMethodContent'),
- ),
- 'variableArrow' => array(
- T_STRING => array('methodOrProperty', 'potentialMethodCall'),
- T_WHITESPACE => array('', 'potentialMethodCall'),
- '*' => array('methodBody', 'appendMethodContent'),
- ),
- 'methodOrProperty' => array(
- '(' => array('methodCall', 'potentialMethodCall'),
- T_WHITESPACE => array('', 'potentialMethodCall'),
- '*' => array('methodBody', 'appendMethodContent'),
- ),
- 'methodCall' => array(
- '(' => array('!push/nestedInMethodCall', 'potentialMethodCall'),
- ')' => array('methodBody', 'completeMethodCall'),
- '*' => array('', 'potentialMethodCall'),
- ),
- 'nestedInMethodCall' => array(
- '(' => array('!push', 'potentialMethodCall'),
- ')' => array('!pop', 'potentialMethodCall'),
- '*' => array('', 'potentialMethodCall'),
- ),
- );
-
- function init() {
- parent::init();
-
- $canAccess = (Director::isDev() || Director::is_cli() || Permission::check("ADMIN"));
- if(!$canAccess) return Security::permissionFailure($this);
- }
-
- function createClass($token) {
- $this->currentClass = array();
- }
- function setClassName($token) {
- $this->currentClass['name'] = $token[1];
- }
- function completeClass($token) {
- $this->classes[] = $this->currentClass;
- }
-
- function createBodyMethod($token) {
- $this->currentMethod = array();
- $this->currentMethod['content'] = "";
- }
- function setMethodName($token) {
- $this->currentMethod['name'] = $token[1];
- }
- function appendMethodComment($token) {
- if(substr($token[1],0,2) == '/*') {
- $comment = preg_replace('/^\/\*/','',$token[1]);
- $comment = preg_replace('/\*\/$/','',$comment);
- $comment = preg_replace('/\n[\t ]*\* */m',"\n",$comment);
-
- $this->closeOffMethodContentPre();
- $this->currentMethod['content'] .= "$comment
";
- } else {
- $this->currentMethod['content'] .= $this->renderToken($token);
- }
-
- }
- function appendMethodContent($token) {
- if($this->potentialMethodCall) {
- $this->currentMethod['content'] .= $this->potentialMethodCall;
- $this->potentialMethodCall = "";
- }
- $this->currentMethod['content'] .= $this->renderToken($token);
- }
- function completeMethod($token) {
- $this->closeOffMethodContentPre();
- $this->currentMethod['content'] = str_replace("\n\t\t","\n",$this->currentMethod['content']);
- $this->currentClass['methods'][] = $this->currentMethod;
- }
-
- protected $potentialMethodCall = "";
- function potentialMethodCall($token) {
- $this->potentialMethodCall .= $this->renderToken($token);
- }
- function completeMethodCall($token) {
- $this->potentialMethodCall .= $this->renderToken($token);
- if(strpos($this->potentialMethodCall, '-> assert') !== false) {
- $this->currentMethod['content'] .= "" . $this->potentialMethodCall . " ";
- } else {
- $this->currentMethod['content'] .= $this->potentialMethodCall;
- }
- $this->potentialMethodCall = "";
- }
-
- /**
- * Finish the "pre" block in method content.
- * Will remove whitespace and empty "pre" blocks
- */
- function closeOffMethodContentPre() {
- $this->currentMethod['content'] = trim($this->currentMethod['content']);
- if(substr($this->currentMethod['content'],-5) == '') $this->currentMethod['content'] = substr($this->currentMethod['content'], 0,-5);
- else $this->currentMethod['content'] .= ' ';
- }
-
- /**
- * Render the given token as HTML
- */
- function renderToken($token) {
- $tokenContent = htmlentities(
- is_array($token) ? $token[1] : $token,
- ENT_COMPAT,
- 'UTF-8'
- );
- $tokenName = is_array($token) ? token_name($token[0]) : 'T_PUNCTUATION';
-
- switch($tokenName) {
- case "T_WHITESPACE":
- return $tokenContent;
- default:
- return "$tokenContent ";
- }
- }
-
- protected $classes = array();
- protected $currentMethod, $currentClass;
-
- function Content() {
- $className = $this->urlParams['ID'];
- if($className && ClassInfo::exists($className)) {
- return $this->testAnalysis(getClassFile($className));
- } else {
- $result = "View any of the following test classes ";
- $classes = ClassInfo::subclassesFor('SapphireTest');
- ksort($classes);
- foreach($classes as $className) {
- if($className == 'SapphireTest') continue;
- $result .= "$className ";
- }
- return $result;
- }
- }
-
- function testAnalysis($file) {
- $content = file_get_contents($file);
- $tokens = token_get_all($content);
-
- // Execute a finite-state-machine with a built-in state stack
- // This FSM+stack gives us enough expressive power for simple PHP parsing
- $state = "start";
- $stateStack = array();
-
- //echo "state $state";
- foreach($tokens as $token) {
- // Get token name - some tokens are arrays, some arent'
- if(is_array($token)) $tokenName = $token[0]; else $tokenName = $token;
- //echo " token '$tokenName'";
-
- // Find the rule for that token in the current state
- if(isset(self::$fsm[$state][$tokenName])) $rule = self::$fsm[$state][$tokenName];
- else if(isset(self::$fsm[$state]['*'])) $rule = self::$fsm[$state]['*'];
- else $rule = null;
-
- // Check to see if we have specified multiple rules depending on whether the stack is populated
- if(is_array($rule) && array_keys($rule) == array('hasstack', 'nostack')) {
- if($stateStack) $rule = $rule['hasstack'];
- else $rule = $rule = $rule['nostack'];
- }
-
- if(is_array($rule)) {
- list($destState, $methodName) = $rule;
- $this->$methodName($token);
- } else if($rule) {
- $destState = $rule;
- } else {
- $destState = null;
- }
- //echo " ->state $destState";
-
- if(preg_match('/!(push|pop)(\/[a-zA-Z0-9]+)?/', $destState, $parts)) {
- $action = $parts[1];
- $argument = isset($parts[2]) ? substr($parts[2],1) : null;
- $destState = null;
-
- switch($action) {
- case "push":
- $stateStack[] = $state;
- if($argument) $destState = $argument;
- break;
-
- case "pop":
- if($stateStack) $destState = array_pop($stateStack);
- else if($argument) $destState = $argument;
- else user_error("State transition '!pop' was attempted with an empty state-stack and no default option specified.", E_USER_ERROR);
- }
- }
-
- if($destState) $state = $destState;
- if(!isset(self::$fsm[$state])) user_error("Transition to unrecognised state '$state'", E_USER_ERROR);
- }
-
- $subclasses = ClassInfo::subclassesFor('SapphireTest');
- foreach($this->classes as $classDef) {
- if(in_array($classDef['name'], $subclasses)) {
- echo "$classDef[name] ";
- if($classDef['methods']) foreach($classDef['methods'] as $method) {
- if(substr($method['name'],0,4) == 'test') {
- //$title = ucfirst(strtolower(preg_replace('/([a-z])([A-Z])/', '$1 $2', substr($method['name'], 4))));
- $title = $method['name'];
-
- echo "$title ";
- echo $method['content'];
- }
- }
- }
-
- }
- }
-}
diff --git a/scss/CodeViewer.scss b/scss/CodeViewer.scss
deleted file mode 100755
index 621ee4318..000000000
--- a/scss/CodeViewer.scss
+++ /dev/null
@@ -1,14 +0,0 @@
-pre {
- border: 1px #777 solid;
- background-color: #CCC;
- color: #333;
- margin: 0.5em 2em;
- padding: 1em;
- line-height: 120%;
-}
-
-pre strong {
- background-color: #FFC;
- color: #000;
- padding: 2px;
-}
\ No newline at end of file
diff --git a/scss/TestViewer.scss b/scss/TestViewer.scss
deleted file mode 100755
index 621ee4318..000000000
--- a/scss/TestViewer.scss
+++ /dev/null
@@ -1,14 +0,0 @@
-pre {
- border: 1px #777 solid;
- background-color: #CCC;
- color: #333;
- margin: 0.5em 2em;
- padding: 1em;
- line-height: 120%;
-}
-
-pre strong {
- background-color: #FFC;
- color: #000;
- padding: 2px;
-}
\ No newline at end of file
diff --git a/templates/CodeViewer.ss b/templates/CodeViewer.ss
deleted file mode 100644
index e87b0648b..000000000
--- a/templates/CodeViewer.ss
+++ /dev/null
@@ -1,9 +0,0 @@
-
-
-<% base_tag %>
-
-
-
- $Content
-
-
diff --git a/templates/ModelViewer.ss b/templates/ModelViewer.ss
deleted file mode 100644
index a155caadb..000000000
--- a/templates/ModelViewer.ss
+++ /dev/null
@@ -1,34 +0,0 @@
-
-
- <% base_tag %>
- Data Model
-
-
-
- Data Model for your project
-
- <% control Modules %>
- Module $Name
-
-
-
- <% control Models %>
- $Name <% if ParentModel %> (subclass of $ParentModel)<% end_if %>
- Fields
-
- <% control Fields %>
- $Name - $Type
- <% end_control %>
-
-
- Relations
-
- <% control Relations %>
- $Name $RelationType $RelatedClass
- <% end_control %>
-
- <% end_control %>
- <% end_control %>
-
-
-
diff --git a/templates/ModelViewer_dotsrc.ss b/templates/ModelViewer_dotsrc.ss
deleted file mode 100644
index a7070a6f2..000000000
--- a/templates/ModelViewer_dotsrc.ss
+++ /dev/null
@@ -1,20 +0,0 @@
-digraph g {
- orientation=portrait;
- overlap=false;
- splines=true;
-
- edge[fontsize=8,len=1.5];
- node[fontsize=10,shape=box];
-
- <% control Modules %>
- <% control Models %>
- $Name [shape=record,label="{$Name|<% control Fields %>$Name\\n<% end_control %>}"];
- <% if ParentModel %>
- $Name -> $ParentModel [style=dotted];
- <% end_if %>
- <% control Relations %>
- $Model.Name -> $RelatedClass [label="$Name\\n$RelationType"];
- <% end_control %>
- <% end_control %>
- <% end_control %>
-}
diff --git a/templates/TestViewer.ss b/templates/TestViewer.ss
deleted file mode 100644
index e14ea0878..000000000
--- a/templates/TestViewer.ss
+++ /dev/null
@@ -1,9 +0,0 @@
-
-
-<% base_tag %>
-
-
-
- $Content
-
-
From 705a29d00a81a30b2f234c97d74a207c9747017e Mon Sep 17 00:00:00 2001
From: Mateusz Uzdowski
Date: Tue, 17 Apr 2012 14:46:07 +1200
Subject: [PATCH 2/2] BUGFIX: fix the ClassInfo::allClasses to fetch manifest
data directly
---
core/ClassInfo.php | 6 +++---
1 file changed, 3 insertions(+), 3 deletions(-)
diff --git a/core/ClassInfo.php b/core/ClassInfo.php
index 27a719a77..39baa1765 100644
--- a/core/ClassInfo.php
+++ b/core/ClassInfo.php
@@ -8,11 +8,11 @@
* @subpackage core
*/
class ClassInfo {
- /**
- * @todo Improve documentation
+ /**
+ * Wrapper for classes getter.
*/
static function allClasses() {
- return SS_ClassLoader::instance()->allClasses();
+ return SS_ClassLoader::instance()->getManifest()->getClasses();
}
/**