/**
 * autoload the Triumph classes.
 */
function autoload($className)
{
    $className = ltrim($className, '\\');
    $fileName = '';
    $namespace = '';
    if ($lastNsPos = strrpos($className, '\\')) {
        $namespace = substr($className, 0, $lastNsPos);
        $className = substr($className, $lastNsPos + 1);
        $fileName = str_replace('\\', DIRECTORY_SEPARATOR, $namespace) . DIRECTORY_SEPARATOR;
    }
    $dir = dirname(__FILE__) . '\\src\\';
    if (\opstring\begins_with($className, 'Zend_')) {
        // Triumph code will not use requires to load in zend framework files
        // we will use this autoloader too
        $dir = dirname(__FILE__) . '\\lib\\';
    }
    $dir = str_replace('\\', DIRECTORY_SEPARATOR, $dir);
    $fileName .= str_replace('_', DIRECTORY_SEPARATOR, $className) . '.php';
    require $dir . $fileName;
}
 function testBeginsWithShouldReturnFalse()
 {
     $this->assertEquals(FALSE, \opstring\begins_with('/home/users', 'users'));
     $this->assertEquals(FALSE, \opstring\begins_with('/home/users', 'root'));
 }
/**
 * This function will use the resource cache to lookup all controllers and their methods.  Then it
 * will create a Triumph_Url instance for each method; note that the routes file is 
 * also consulted and we will generate URLs for the default controller.
 *
 * @param  string  $sourceDir            the root directory of the project in question
 * @param  string  $resourceDbFileName   the location of the resource cache SQLite file; as created by Triumph
 * @param  string  $host                 the hostname of the application; this will be used a the prefix on all URLs
 * @param  boolean $doSkip               out parameter; if TRUE then this detector does not know how
 *                                       to detect URLs for the given source directory; this situation
 *                                       is different than zero URLs being detected.
 * @return Triumph_Url[]               array of Triumph_Url instances the detected URLs
 */
function detectUrls($sourceDir, $resourceDbFileName, $host, &$doSkip)
{
    $doSkip = TRUE;
    if (!is_file($resourceDbFileName)) {
        return array();
    }
    $sourceDir = \opstring\ensure_ends_with($sourceDir, DIRECTORY_SEPARATOR);
    $host = \opstring\ensure_ends_with($host, '/');
    // TODO: handle multiple apps
    // need this define so that we can include code igniter files directly
    if (!defined('BASEPATH')) {
        define('BASEPATH', '');
    }
    if (!is_file($sourceDir . 'application/config/routes.php') || !is_file($sourceDir . 'application/config/config.php')) {
        // this source directory does not contain a code igniter directory.
        return array();
    }
    $doSkip = FALSE;
    // get the code igniter configuration so that we can use it to build the
    // correct routes
    $config = array();
    $route = array();
    include $sourceDir . 'application/config/routes.php';
    include $sourceDir . 'application/config/config.php';
    $allUrls = array();
    // lookup all controller files from the resource cache, only controllers are accessible via URLs
    // since file names in the cache are OS dependant, need to use the correct directory separators
    $pdo = Zend_Db::factory('Pdo_Sqlite', array("dbname" => $resourceDbFileName));
    $fileItemTable = new Triumph_FileItemTable($pdo);
    $controllerDir = $sourceDir . 'application' . DIRECTORY_SEPARATOR . 'controllers';
    $matchingFiles = $fileItemTable->MatchingFiles($controllerDir);
    // lookup all of the methods for all controller files.
    $resourceTable = new Triumph_ResourceTable($pdo);
    $methods = $resourceTable->PublicMethodsFromFiles($matchingFiles);
    foreach ($methods as $resource) {
        // need to handle any sub-directories underneath the controllers; as the subdirectory
        // is propagated in the URL
        $controllerFile = \opstring\after($resource->fullPath, $controllerDir);
        $subDirectory = dirname($controllerFile);
        if ('\\' == $subDirectory || '/' == $subDirectory) {
            // hack to work around special case when there is no subdirectory
            $subDirectory = '';
        }
        // constructors are not web-accessible
        // code igniter makes methods that start with underscore
        if (\opstring\compare_case('__construct', $resource->identifier) && !\opstring\begins_with($resource->identifier, '_')) {
            // TODO: any controller arguments ... should get these from the user somehow
            $extra = '';
            $appUrl = makeUrl($route, $config, $subDirectory, $resource->fullPath, $resource->className, $resource->identifier, $extra);
            $appUrl->url = $host . $appUrl->url;
            $allUrls[] = $appUrl;
        }
    }
    return $allUrls;
}