/**
  * @return Array
  */
 public static function get_all_tests()
 {
     ManifestBuilder::load_test_manifest();
     $tests = ClassInfo::subclassesFor('SapphireTest');
     array_shift($tests);
     return $tests;
 }
 function init()
 {
     parent::init();
     if (!Permission::check('ADMIN')) {
         return Security::permissionFailure();
     }
     ManifestBuilder::load_test_manifest();
 }
 function init()
 {
     parent::init();
     ManifestBuilder::load_test_manifest();
     if (!self::$default_reporter) {
         self::set_reporter(Director::is_cli() ? 'CliDebugView' : 'DebugView');
     }
 }
 /**
  * Get all available themes that haven't been marked as disabled.
  * @param string $baseDir Optional alternative theme base directory for testing
  * @return array of theme directory names
  */
 public function getAvailableThemes($baseDir = null)
 {
     $themes = ManifestBuilder::get_themes($baseDir);
     foreach (self::$disabled_themes as $theme) {
         if (isset($themes[$theme])) {
             unset($themes[$theme]);
         }
     }
     return $themes;
 }
 function testInterfaceDefParser()
 {
     $parser = ManifestBuilder::getInterfaceDefParser();
     $tokens = $this->getTokens();
     $matches = $parser->findAll($tokens);
     $interfaces = array();
     if ($matches) {
         foreach ($matches as $match) {
             $interfaces[$match['interfaceName']] = $match;
         }
     }
     $this->assertArrayHasKey('InterfaceA', $interfaces);
     $this->assertArrayHasKey('InterfaceB', $interfaces);
     $this->assertEquals('Something', $interfaces['InterfaceB']['extends']);
 }
Beispiel #6
0
 /**
  * Updates the database schema, creating tables & fields as necessary.
  */
 function build()
 {
     // The default time limit of 30 seconds is normally not enough
     increase_time_limit_to(600);
     // Get all our classes
     ManifestBuilder::create_manifest_file();
     require MANIFEST_FILE;
     if (isset($_GET['returnURL'])) {
         echo "<p>Setting up the database; you will be returned to your site shortly....</p>";
         $this->doBuild(true);
         echo "<p>Done!</p>";
         Director::redirect($_GET['returnURL']);
     } else {
         $this->doBuild(isset($_REQUEST['quiet']) || isset($_REQUEST['from_installer']), !isset($_REQUEST['dont_populate']));
     }
 }
 function testManifestIgnoresClassesInStrings()
 {
     $baseFolder = TEMP_FOLDER . '/manifest-test';
     $manifestInfo = ManifestBuilder::get_manifest_info($baseFolder);
     /* If a class defintion is listed in a single quote string, then it shouldn't be inlcuded.  Here we have put a class definition for  MyClass_InSingleQuoteString inside a single-quoted string */
     $this->assertNotContains('MyClass_InSingleQuoteString', array_keys($manifestInfo['globals']['_CLASS_MANIFEST']));
     $this->assertNotContains('MyClass_InSingleQuoteString', array_keys($manifestInfo['globals']['_ALL_CLASSES']['exists']));
     $this->assertNotContains('MyClass_InSingleQuoteString', array_keys($manifestInfo['globals']['_ALL_CLASSES']['parents']));
     /* Ditto for double quotes.  Here we have put a class definition for MyClass_InDoubleQuoteString inside a double-quoted string.  */
     $this->assertNotContains('MyClass_InDoubleQuoteString', array_keys($manifestInfo['globals']['_CLASS_MANIFEST']));
     $this->assertNotContains('MyClass_InDoubleQuoteString', array_keys($manifestInfo['globals']['_ALL_CLASSES']['exists']));
     $this->assertNotContains('MyClass_InDoubleQuoteString', array_keys($manifestInfo['globals']['_ALL_CLASSES']['parents']));
     /* Finally, we need to ensure that class definitions inside heredoc strings aren't included.  Here, we have defined the class MyClass_InHeredocString inside a heredoc string. */
     $this->assertNotContains('MyClass_InHeredocString', array_keys($manifestInfo['globals']['_CLASS_MANIFEST']));
     $this->assertNotContains('MyClass_InHeredocString', array_keys($manifestInfo['globals']['_ALL_CLASSES']['exists']));
     $this->assertNotContains('MyClass_InHeredocString', array_keys($manifestInfo['globals']['_ALL_CLASSES']['parents']));
 }
 /**
  * Updates the database schema, creating tables & fields as necessary.
  */
 function build()
 {
     // The default time limit of 30 seconds is normally not enough
     increase_time_limit_to(600);
     // Get all our classes
     ManifestBuilder::create_manifest_file();
     require MANIFEST_FILE;
     if (isset($_GET['returnURL'])) {
         echo "<p>Setting up the database; you will be returned to your site shortly....</p>";
         $this->doBuild(true);
         echo "<p>Done!</p>";
         Director::redirect($_GET['returnURL']);
     } else {
         if (!Director::is_cli() && Director::urlParam('Controller') == __CLASS__) {
             echo '<p style="color: red;"><i>db/build</i> has been deprecated. Please use <b>dev/build</b> instead.</p>';
         }
         $this->doBuild(isset($_REQUEST['quiet']) || isset($_REQUEST['from_installer']), !isset($_REQUEST['dont_populate']));
     }
 }
	/**
	 * Updates the database schema, creating tables & fields as necessary.
	 */
	function build() {
		if(Director::isLive() && Security::database_is_ready() && !Director::is_cli() && !Permission::check("ADMIN")) {
			Security::permissionFailure($this,
				"This page is secured and you need administrator rights to access it. " .
				"Enter your credentials below and we will send you right along.");
			return;
		}

		// The default time limit of 30 seconds is normally not enough
		if(ini_get("safe_mode") != "1") {
			set_time_limit(600);
		}

		// Get all our classes
		ManifestBuilder::create_manifest_file();
		require(MANIFEST_FILE);
		
		$this->doBuild(isset($_REQUEST['quiet']) || isset($_REQUEST['from_installer']), !isset($_REQUEST['dont_populate']));
	}
Beispiel #10
0
	/**
	 * Build a {@link SQLQuery} object to perform the given query.
	 *
	 * @param string $filter A filter to be inserted into the WHERE clause.
	 * @param string|array $sort A sort expression to be inserted into the ORDER BY clause. If omitted, self::$default_sort will be used.
	 * @param string|array $limit A limit expression to be inserted into the LIMIT clause.
	 * @param string $join A single join clause. This can be used for filtering, only 1 instance of each DataObject will be returned.
	 * @param boolean $restictClasses Restrict results to only objects of either this class of a subclass of this class
	 * @param string $having A filter to be inserted into the HAVING clause.
	 *
	 * @return SQLQuery Query built.
	 */
	public function buildSQL($filter = "", $sort = "", $limit = "", $join = "", $restrictClasses = true, $having = "") {
		// Find a default sort
		if(!$sort) {
			$sort = $this->stat('default_sort');
		}

		// Get the tables to join to
		$tableClasses = ClassInfo::dataClassesFor($this->class);
		if(!$tableClasses) {
			if(!ManifestBuilder::has_been_included()) {
				user_error("DataObjects have been requested before the manifest is loaded. Please ensure you are not querying the database in _config.php.", E_USER_ERROR);
			} else {
				user_error("DataObject::buildSQL: Can't find data classes (classes linked to tables) for $this->class. Please ensure you run dev/build after creating a new DataObject.", E_USER_ERROR);
			}
		}

		$baseClass = array_shift($tableClasses);
		$select = array("`$baseClass`.*");

		// Build our intial query
		$query = new SQLQuery($select);
		$query->from("`$baseClass`");
		$query->where($filter);
		$query->orderby($sort);
		$query->limit($limit);

		// Add SQL for multi-value fields on the base table
		$databaseFields = $this->databaseFields();
		if($databaseFields) foreach($databaseFields as $k => $v) {
			if(!in_array($k, array('ClassName', 'LastEdited', 'Created'))) {
				if(ClassInfo::classImplements($v, 'CompositeDBField')) {
					$this->dbObject($k)->addToQuery($query);
				}
			}
		}
		// Join all the tables
		if($tableClasses && self::$subclass_access) {
			foreach($tableClasses as $tableClass) {
				$query->from[$tableClass] = "LEFT JOIN `$tableClass` ON `$tableClass`.ID = `$baseClass`.ID";
				$query->select[] = "`$tableClass`.*";

				// Add SQL for multi-value fields
				$SNG = singleton($tableClass);
				$databaseFields = $SNG->databaseFields();
				if($databaseFields) foreach($databaseFields as $k => $v) {
					if(!in_array($k, array('ClassName', 'LastEdited', 'Created'))) {
						if(ClassInfo::classImplements($v, 'CompositeDBField')) {
							$SNG->dbObject($k)->addToQuery($query);
						}
					}
				}
			}
		}

		$query->select[] = "`$baseClass`.ID";
		$query->select[] = "if(`$baseClass`.ClassName,`$baseClass`.ClassName,'$baseClass') AS RecordClassName";

		// Get the ClassName values to filter to
		$classNames = ClassInfo::subclassesFor($this->class);

		if(!$classNames) {
			user_error("DataObject::get() Can't find data sub-classes for '$callerClass'");
		}

		// If querying the base class, don't bother filtering on class name
		if($restrictClasses && $this->class != $baseClass) {
			// Get the ClassName values to filter to
			$classNames = ClassInfo::subclassesFor($this->class);
			if(!$classNames) {
				user_error("DataObject::get() Can't find data sub-classes for '$callerClass'");
			}

			$query->where[] = "`$baseClass`.ClassName IN ('" . implode("','", $classNames) . "')";
		}

		if($having) {
			$query->having[] = $having;
		}

		if($join) {
			$query->from[] = $join;
			$query->groupby[] = reset($query->from) . ".ID";
		}

		return $query;
	}
Beispiel #11
0
// Find the URL of this script
if (isset($_FILE_TO_URL_MAPPING)) {
    $fullPath = $testPath = $_SERVER['SCRIPT_FILENAME'];
    while ($testPath && $testPath != "/") {
        if (isset($_FILE_TO_URL_MAPPING[$testPath])) {
            $url = $_FILE_TO_URL_MAPPING[$testPath] . substr($fullPath, strlen($testPath));
            $_SERVER['HTTP_HOST'] = parse_url($url, PHP_URL_HOST);
            $_SERVER['SCRIPT_NAME'] = parse_url($url, PHP_URL_PATH);
            $_SERVER['REQUEST_PORT'] = parse_url($url, PHP_URL_PORT);
            break;
        }
        $testPath = dirname($testPath);
    }
}
if (ManifestBuilder::staleManifest()) {
    ManifestBuilder::compileManifest();
}
require_once MANIFEST_FILE;
if (isset($_GET['debugmanifest'])) {
    Debug::show(file_get_contents(MANIFEST_FILE));
}
if (!isset(Director::$environment_type)) {
    Director::set_environment_type($envType);
}
// Default director
Director::addRules(10, array('Security/$Action' => 'Security', 'db/$Action' => 'DatabaseAdmin', '$Controller/$Action/$ID/$OtherID' => '*', 'images/$Action/$Class/$ID/$Field' => 'Image_Uploader', '' => '->home/', '$URLSegment/$Action/$ID/$OtherID' => 'ModelAsController'));
// Load error handlers
Debug::loadErrorHandlers();
// Connect to database
require_once "core/model/DB.php";
DB::connect($databaseConfig);
<?php

// Simulate an execution from sapphire/cli-script.php, Core.php has too many
// hardcoded assumptions about folder depth of the executing script.
// Overrides paths relative to this file (in sapphire/tests/FullTestSuite.php)
$_SERVER['SCRIPT_FILENAME'] = dirname(dirname(__FILE__)) . DIRECTORY_SEPARATOR . 'cli-script.php';
$_SERVER['SCRIPT_NAME'] = '.' . DIRECTORY_SEPARATOR . 'sapphire' . DIRECTORY_SEPARATOR . 'cli-script.php';
define('BASE_PATH', rtrim(dirname(dirname(dirname(__FILE__)))), DIRECTORY_SEPARATOR);
// Copied from cli-script.php, to enable same behaviour through phpunit runner.
if (isset($_SERVER['argv'][2])) {
    $args = array_slice($_SERVER['argv'], 2);
    $_GET = array();
    foreach ($args as $arg) {
        if (strpos($arg, '=') == false) {
            $_GET['args'][] = $arg;
        } else {
            $newItems = array();
            parse_str(substr($arg, 0, 2) == '--' ? substr($arg, 2) : $arg, $newItems);
            $_GET = array_merge($_GET, $newItems);
        }
    }
    $_REQUEST = $_GET;
}
if (!class_exists('Object')) {
    require_once "sapphire/core/Core.php";
    global $databaseConfig;
    DB::connect($databaseConfig);
}
$_SERVER['REQUEST_URI'] = BASE_URL . '/dev';
ManifestBuilder::load_test_manifest();
Beispiel #13
0
 /**
  * Updates the database schema, creating tables & fields as necessary.
  *
  * @param boolean $quiet Don't show messages
  * @param boolean $populate Populate the database, as well as setting up its schema
  */
 function doBuild($quiet = false, $populate = true)
 {
     $conn = DB::getConn();
     if ($quiet) {
         DB::quiet();
     } else {
         echo "<h2>Building Database</h2>";
     }
     // Set up the initial database
     if (!DB::isActive()) {
         if (!$quiet) {
             echo '<p><b>Creating database</b></p>';
         }
         global $databaseConfig;
         $parameters = $databaseConfig ? $databaseConfig : $_REQUEST['db'];
         $connect = DB::getConnect($parameters);
         $username = $parameters['username'];
         $password = $parameters['password'];
         $database = $parameters['database'];
         DB::createDatabase($connect, $username, $password, $database);
         // ManifestBuilder::compileManifest();
     }
     // Get all our classes
     // ManifestBuilder::compileManifest();
     // ManifestBuilder::includeEverything();
     // Build the database.  Most of the hard work is handled by DataObject
     $dataClasses = ClassInfo::subclassesFor('DataObject');
     array_shift($dataClasses);
     if (!$quiet) {
         echo '<p><b>Creating database tables</b></p>';
     }
     $conn->beginSchemaUpdate();
     foreach ($dataClasses as $dataClass) {
         // Test_ indicates that it's the data class is part of testing system
         if (strpos($dataClass, 'Test_') === false) {
             if (!$quiet) {
                 echo "<li>{$dataClass}</li>";
             }
             singleton($dataClass)->requireTable();
         }
     }
     $conn->endSchemaUpdate();
     ManifestBuilder::update_db_tables();
     if ($populate) {
         if (!$quiet) {
             echo '<p><b>Creating database records</b></p>';
         }
         foreach ($dataClasses as $dataClass) {
             // Test_ indicates that it's the data class is part of testing system
             if (strpos($dataClass, 'Test_') === false) {
                 if (!$quiet) {
                     echo "<li>{$dataClass}</li>";
                 }
                 singleton($dataClass)->requireDefaultRecords();
             }
         }
     }
     touch(TEMP_FOLDER . '/database-last-generated-' . str_replace(array('\\', '/', ':'), '.', Director::baseFolder()));
     if (isset($_REQUEST['from_installer'])) {
         echo "OK";
     }
 }
 /**
  * Build a {@link SQLQuery} object to perform the given query.
  *
  * @param string $filter A filter to be inserted into the WHERE clause.
  * @param string|array $sort A sort expression to be inserted into the ORDER BY clause. If omitted, self::$default_sort will be used.
  * @param string|array $limit A limit expression to be inserted into the LIMIT clause.
  * @param string $join A single join clause. This can be used for filtering, only 1 instance of each DataObject will be returned.
  * @param boolean $restictClasses Restrict results to only objects of either this class of a subclass of this class
  * @param string $having A filter to be inserted into the HAVING clause.
  *
  * @return SQLQuery Query built.
  */
 public function buildSQL($filter = "", $sort = "", $limit = "", $join = "", $restrictClasses = true, $having = "")
 {
     // Cache the big hairy part of buildSQL
     if (!isset(self::$cache_buildSQL_query[$this->class])) {
         // Get the tables to join to
         $tableClasses = ClassInfo::dataClassesFor($this->class);
         if (!$tableClasses) {
             if (!ManifestBuilder::has_been_included()) {
                 user_error("DataObjects have been requested before the manifest is loaded. Please ensure you are not querying the database in _config.php.", E_USER_ERROR);
             } else {
                 user_error("DataObject::buildSQL: Can't find data classes (classes linked to tables) for {$this->class}. Please ensure you run dev/build after creating a new DataObject.", E_USER_ERROR);
             }
         }
         $baseClass = array_shift($tableClasses);
         // $collidingFields will keep a list fields that appear in mulitple places in the class
         // heirarchy for this table.  They will be dealt with more explicitly in the SQL query
         // to ensure that junk data from other tables doesn't corrupt data objects
         $collidingFields = array();
         // Build our intial query
         $query = new SQLQuery(array());
         $query->from("\"{$baseClass}\"");
         // Add SQL for multi-value fields on the base table
         $databaseFields = self::database_fields($baseClass);
         if ($databaseFields) {
             foreach ($databaseFields as $k => $v) {
                 if (!in_array($k, array('ClassName', 'LastEdited', 'Created')) && ClassInfo::classImplements($v, 'CompositeDBField')) {
                     $this->dbObject($k)->addToQuery($query);
                 } else {
                     $query->select[$k] = "\"{$baseClass}\".\"{$k}\"";
                 }
             }
         }
         // Join all the tables
         if ($tableClasses && self::$subclass_access) {
             foreach ($tableClasses as $tableClass) {
                 $query->from[$tableClass] = "LEFT JOIN \"{$tableClass}\" ON \"{$tableClass}\".\"ID\" = \"{$baseClass}\".\"ID\"";
                 // Add SQL for multi-value fields
                 $databaseFields = self::database_fields($tableClass);
                 $compositeFields = self::composite_fields($tableClass, false);
                 if ($databaseFields) {
                     foreach ($databaseFields as $k => $v) {
                         if (!isset($compositeFields[$k])) {
                             // Update $collidingFields if necessary
                             if (isset($query->select[$k])) {
                                 if (!isset($collidingFields[$k])) {
                                     $collidingFields[$k] = array($query->select[$k]);
                                 }
                                 $collidingFields[$k][] = "\"{$tableClass}\".\"{$k}\"";
                             } else {
                                 $query->select[$k] = "\"{$tableClass}\".\"{$k}\"";
                             }
                         }
                     }
                 }
                 if ($compositeFields) {
                     foreach ($compositeFields as $k => $v) {
                         $dbO = $this->dbObject($k);
                         if ($dbO) {
                             $dbO->addToQuery($query);
                         }
                     }
                 }
             }
         }
         // Resolve colliding fields
         if ($collidingFields) {
             foreach ($collidingFields as $k => $collisions) {
                 $caseClauses = array();
                 foreach ($collisions as $collision) {
                     if (preg_match('/^"([^"]+)"/', $collision, $matches)) {
                         $collisionBase = $matches[1];
                         $collisionClasses = ClassInfo::subclassesFor($collisionBase);
                         $caseClauses[] = "WHEN \"{$baseClass}\".\"ClassName\" IN ('" . implode("', '", $collisionClasses) . "') THEN {$collision}";
                     } else {
                         user_error("Bad collision item '{$collision}'", E_USER_WARNING);
                     }
                 }
                 $query->select[$k] = "CASE " . implode(" ", $caseClauses) . " ELSE NULL END" . " AS \"{$k}\"";
             }
         }
         $query->select[] = "\"{$baseClass}\".\"ID\"";
         $query->select[] = "CASE WHEN \"{$baseClass}\".\"ClassName\" IS NOT NULL THEN \"{$baseClass}\".\"ClassName\" ELSE '{$baseClass}' END AS \"RecordClassName\"";
         // Get the ClassName values to filter to
         $classNames = ClassInfo::subclassesFor($this->class);
         if (!$classNames) {
             user_error("DataObject::get() Can't find data sub-classes for '{$callerClass}'");
         }
         // If querying the base class, don't bother filtering on class name
         if ($restrictClasses && $this->class != $baseClass) {
             // Get the ClassName values to filter to
             $classNames = ClassInfo::subclassesFor($this->class);
             if (!$classNames) {
                 user_error("DataObject::get() Can't find data sub-classes for '{$callerClass}'");
             }
             $query->where[] = "\"{$baseClass}\".\"ClassName\" IN ('" . implode("','", $classNames) . "')";
         }
         self::$cache_buildSQL_query[$this->class] = clone $query;
     } else {
         $query = clone self::$cache_buildSQL_query[$this->class];
     }
     // Find a default sort
     if (!$sort) {
         $sort = $this->stat('default_sort');
     }
     // Add quoting to sort expression if it's a simple column name
     if (preg_match('/^[A-Z][A-Z0-9_]*$/i', $sort)) {
         $sort = "\"{$sort}\"";
     }
     $query->where($filter);
     $query->orderby($sort);
     $query->limit($limit);
     if ($having) {
         $query->having[] = $having;
     }
     if ($join) {
         $query->from[] = $join;
         // In order to group by unique columns we have to group by everything listed in the select
         foreach ($query->select as $field) {
             // Skip the _SortColumns; these are only going to be aggregate functions
             if (preg_match('/AS\\s+\\"?_SortColumn/', $field, $matches)) {
                 // Identify columns with aliases, and ignore the alias.  Making use of the alias in
                 // group by was causing problems when those queries were subsequently passed into
                 // SQLQuery::unlimitedRowCount.
             } else {
                 if (preg_match('/^(.*)\\s+AS\\s+(\\"[^"]+\\")\\s*$/', $field, $matches)) {
                     $query->groupby[] = $matches[1];
                     // Otherwise just use the field as is
                 } else {
                     $query->groupby[] = $field;
                 }
             }
         }
     }
     return $query;
 }
Beispiel #15
0
	function coverage() {
		if(hasPhpUnit()) {
			ManifestBuilder::load_all_classes();
			$tests = ClassInfo::subclassesFor('SapphireTest');
			array_shift($tests);
			unset($tests['FunctionalTest']);
		
			$this->runTests($tests, true);
		} else {
			echo "Please install PHPUnit using pear";
		}
	}
 function testThemeRetrieval()
 {
     $ds = DIRECTORY_SEPARATOR;
     $testThemeBaseDir = TEMP_FOLDER . $ds . 'test-themes';
     if (file_exists($testThemeBaseDir)) {
         Filesystem::removeFolder($testThemeBaseDir);
     }
     mkdir($testThemeBaseDir);
     mkdir($testThemeBaseDir . $ds . 'blackcandy');
     mkdir($testThemeBaseDir . $ds . 'blackcandy_blog');
     mkdir($testThemeBaseDir . $ds . 'darkshades');
     mkdir($testThemeBaseDir . $ds . 'darkshades_blog');
     $this->assertEquals(array('blackcandy' => 'blackcandy', 'darkshades' => 'darkshades'), ManifestBuilder::get_themes($testThemeBaseDir), 'Our test theme directory contains 2 themes');
     $this->assertEquals(array('blackcandy' => 'blackcandy', 'blackcandy_blog' => 'blackcandy_blog', 'darkshades' => 'darkshades', 'darkshades_blog' => 'darkshades_blog'), ManifestBuilder::get_themes($testThemeBaseDir, true), 'Our test theme directory contains 2 themes and 2 sub-themes');
     // Remove all the test themes we created
     Filesystem::removeFolder($testThemeBaseDir);
 }
Beispiel #17
0
 */
increase_memory_limit_to('64M');
///////////////////////////////////////////////////////////////////////////////
// INCLUDES
require_once "core/ManifestBuilder.php";
require_once "core/ClassInfo.php";
require_once 'core/Object.php';
require_once 'core/control/Director.php';
require_once 'filesystem/Filesystem.php';
require_once "core/Session.php";
///////////////////////////////////////////////////////////////////////////////
// MANIFEST
/**
 * Include the manifest
 */
ManifestBuilder::include_manifest();
/**
 * ?debugmanifest=1 hook
 */
if (isset($_GET['debugmanifest'])) {
    Debug::show(file_get_contents(MANIFEST_FILE));
}
// If this is a dev site, enable php error reporting
// This is necessary to force developers to acknowledge and fix
// notice level errors (you can override this directive in your _config.php)
if (Director::isLive()) {
    if (defined('E_DEPRECATED')) {
        error_reporting(E_ALL ^ E_NOTICE ^ E_DEPRECATED);
    } else {
        error_reporting(E_ALL ^ E_NOTICE);
    }
 /**
  * Include everything, so that actually *all* classes are available and
  * build a map of classes and their subclasses
  * 
  * @param $classManifest An array of all Sapphire classes; keys are class names and values are filenames
  *
  * @return array Returns an array that holds all class relevant
  *               information.
  */
 private static function allClasses($classManifest)
 {
     self::$classArray = array();
     self::$extendsArray = array();
     self::$implementsArray = array();
     // Include everything, so we actually have *all* classes
     foreach ($classManifest as $file) {
         $b = basename($file);
         if ($b != 'cli-script.php' && $b != 'main.php') {
             self::parse_file($file);
         }
     }
     $allClasses["parents"] = self::find_parents();
     $allClasses["children"] = self::find_children();
     $allClasses["implementors"] = self::$implementsArray;
     foreach (self::$classArray as $class => $info) {
         $allClasses['exists'][$class] = $class;
     }
     // Build a map of classes and their subclasses
     $_classes = get_declared_classes();
     foreach ($_classes as $class) {
         $allClasses['exists'][$class] = $class;
         foreach ($_classes as $subclass) {
             if (is_subclass_of($class, $subclass)) {
                 $allClasses['parents'][$class][$subclass] = $subclass;
             }
             if (is_subclass_of($subclass, $class)) {
                 $allClasses['children'][$class][$subclass] = $subclass;
             }
         }
     }
     return $allClasses;
 }
 /**
  * Include everything, so that actually *all* classes are available and
  * build a map of classes and their subclasses
  * 
  * @param $classManifest An array of all Sapphire classes; keys are class names and values are filenames
  *
  * @return array Returns an array that holds all class relevant
  *               information.
  */
 private static function allClasses($classManifest)
 {
     self::$classArray = array();
     self::$extendsArray = array();
     self::$implementsArray = array();
     // Include everything, so we actually have *all* classes
     foreach ($classManifest as $file) {
         $b = basename($file);
         if ($b != 'cli-script.php' && $b != 'main.php') {
             self::parse_file($file);
         }
     }
     $allClasses["parents"] = self::find_parents();
     $allClasses["children"] = self::find_children();
     $allClasses["implementors"] = self::$implementsArray;
     foreach (self::$classArray as $class => $info) {
         $allClasses['exists'][$class] = $class;
         // Class names are converted to lowercase for lookup to adhere to PHP's case-insensitive
         // way of dealing with them.
         $allClasses['file'][strtolower($class)] = $info['file'];
     }
     // Build a map of classes and their subclasses
     $_classes = get_declared_classes();
     foreach ($_classes as $class) {
         $allClasses['exists'][$class] = $class;
         foreach ($_classes as $subclass) {
             if (is_subclass_of($class, $subclass)) {
                 $allClasses['parents'][$class][$subclass] = $subclass;
             }
             if (is_subclass_of($subclass, $class)) {
                 $allClasses['children'][$class][$subclass] = $subclass;
             }
         }
     }
     return $allClasses;
 }
Beispiel #20
0
 /**
  * Run tests for one or more "modules".
  * A module is generally a toplevel folder, e.g. "mysite" or "sapphire".
  */
 function module($request, $coverage = false)
 {
     ManifestBuilder::load_test_manifest();
     $classNames = array();
     $moduleNames = explode(',', $request->param('ModuleName'));
     foreach ($moduleNames as $moduleName) {
         $classesForModule = ClassInfo::classes_for_folder($moduleName);
         if ($classesForModule) {
             foreach ($classesForModule as $class) {
                 if (class_exists($class) && is_subclass_of($class, 'SapphireTest')) {
                     $classNames[] = $class;
                 }
             }
         }
     }
     $this->runTests($classNames, $coverage);
 }
Beispiel #21
0
 /**
  * Generates the template manifest - a list of all the .SS files in the
  * application
  */
 private static function getTemplateManifest($baseDir, $folder, &$templateManifest, &$cssManifest, $themeName = null)
 {
     $items = scandir("{$baseDir}/{$folder}");
     if ($items) {
         foreach ($items as $item) {
             if (substr($item, 0, 1) == '.') {
                 continue;
             }
             if (substr($item, -3) == '.ss') {
                 $templateName = substr($item, 0, -3);
                 $templateType = substr($folder, strrpos($folder, '/') + 1);
                 if ($templateType == "templates") {
                     $templateType = "main";
                 }
                 if ($themeName) {
                     $templateManifest[$templateName]['themes'][$themeName][$templateType] = "{$baseDir}/{$folder}/{$item}";
                 } else {
                     $templateManifest[$templateName][$templateType] = "{$baseDir}/{$folder}/{$item}";
                 }
             } else {
                 if (substr($item, -4) == '.css') {
                     $cssName = substr($item, 0, -4);
                     // Debug::message($item);
                     if ($themeName) {
                         $cssManifest[$cssName]['themes'][$themeName] = "{$folder}/{$item}";
                     } else {
                         $cssManifest[$cssName]['unthemed'] = "{$folder}/{$item}";
                     }
                 } else {
                     if (@is_dir("{$baseDir}/{$folder}/{$item}")) {
                         ManifestBuilder::getTemplateManifest($baseDir, "{$folder}/{$item}", $templateManifest, $cssManifest, $themeName);
                     }
                 }
             }
         }
     }
 }