function testCompare()
 {
     $this->assertEquals(-1, \opstring\compare('that', 'this'));
     $this->assertEquals(0, \opstring\compare('this', 'this'));
     $this->assertEquals(1, \opstring\compare('this', 'that'));
     $this->assertEquals(1, \opstring\compare('this', 'thIS'));
 }
/**
 * This function will use the resource cache to lookup all controllers and their methods.  Then it
 * will create a Triumph_TemplateFile instance for each method.
 *
 * @param  string $sourceDir            the root directory of the project in question
 * @param  string $detectorDbFileName   the location of the resource cache SQLite file; as created by Triumph
 * @param  boolean $doSkip              out parameter; if TRUE then this detector does not know how
 *                                      to detect templates for the given source directory; this situation
 *                                      is different than zero templates being detected.
 * @return Triumph_TemplateFile[]     array of Triumph_TemplateFile instances the detected template files and their variables
 */
function detectTemplates($sourceDir, $detectorDbFileName, &$doSkip)
{
    $doSkip = TRUE;
    $allTemplates = array();
    if (!is_file($detectorDbFileName)) {
        return $allTemplates;
    }
    // need to check that this detector is able to recognize the directory structure of sourceDir
    // if not, then we need to skip detection by returning immediately and setting $doSkip to TRUE.
    // by skipping detection, we prevent any detected templates from the previous detection script
    // from being deleted.
    $sourceDir = \opstring\ensure_ends_with($sourceDir, DIRECTORY_SEPARATOR);
    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 $allTemplates;
    }
    $doSkip = FALSE;
    // add your logic here; usually it will consist of querying the SQLite database in $detectorDbFileName
    // recursing though the call stack and picking the method calls for templates.
    $pdo = Zend_Db::factory('Pdo_Sqlite', array("dbname" => $detectorDbFileName));
    $callStackTable = new Triumph_CallStackTable($pdo);
    $callStacks = $callStackTable->load();
    // figure out the variables
    $scopes = $callStackTable->splitScopes($callStacks);
    // now go through each scope, looking for calls to $this->load->view
    foreach ($scopes as $scope) {
        // list of all method calls used to find calls to view method
        $methodCalls = $callStackTable->getMethodCalls($scope);
        // list of all property accesses, make sure that calls to view method
        // are used on the loader member variables
        $propertyCalls = $callStackTable->getPropertyCalls($scope);
        $variableCalls = $callStackTable->getVariables($scope);
        foreach ($methodCalls as $destinationVariable => $call) {
            if (\opstring\compare_case($call->methodName, 'view') == 0 && isset($propertyCalls[$call->objectName])) {
                // is this view call of a loader object ?
                $propertyCall = $propertyCalls[$call->objectName];
                if (\opstring\compare('$this', $propertyCall->objectName) == 0 && (\opstring\compare('load', $propertyCall->propertyName) == 0 || \opstring\compare('loader', $propertyCall->propertyName) == 0)) {
                    $currentTemplate = new Triumph_TemplateFileTag();
                    $currentTemplate->variables = array();
                    $currentTemplate->fullPath = '';
                    if (count($call->functionArguments) >= 1) {
                        // argument 1 of the view method call is the template file
                        // most of the time views are given as relative relatives; starting from the application/views/ directory
                        // for now ignore variable arguments
                        if (isset($variableCalls[$call->functionArguments[0]])) {
                            $variableCall = $variableCalls[$call->functionArguments[0]];
                            if ($variableCall->type == Triumph_CallStack::SCALAR) {
                                $currentTemplate->fullPath = $variableCall->scalarValue;
                                // view file may have an extension; if it has an extension use that; otherwise use the default (.php)
                                if (stripos($currentTemplate->fullPath, '.') === FALSE) {
                                    $currentTemplate->fullPath .= '.php';
                                }
                                // not using realpath() so that Triumph can know that a template file has not yet been created
                                // or the programmer has a bug in the project.
                                $currentTemplate->fullPath = \opstring\replace($currentTemplate->fullPath, '/', DIRECTORY_SEPARATOR);
                                $currentTemplate->fullPath = \opstring\replace($currentTemplate->fullPath, '\\', DIRECTORY_SEPARATOR);
                                $currentTemplate->fullPath = $sourceDir . 'application' . DIRECTORY_SEPARATOR . 'views' . DIRECTORY_SEPARATOR . $currentTemplate->fullPath;
                                // push it now just in case the template does not get any variables
                                $allTemplates[] = $currentTemplate;
                            }
                        }
                    }
                    if (count($call->functionArguments) >= 2 && !empty($currentTemplate->fullPath)) {
                        // argument 2 is an array of template variables
                        if (isset($variableCalls[$call->functionArguments[1]])) {
                            $variableCall = $variableCalls[$call->functionArguments[1]];
                            $arrayKeys = $callStackTable->getArrayKeys($scope, $variableCall->destinationVariable);
                            foreach ($arrayKeys as $key) {
                                // add the siguil here; editor expects us to return variables
                                $currentTemplate->variables[] = '$' . $key;
                            }
                            $allTemplates[count($allTemplates) - 1] = $currentTemplate;
                        }
                    }
                }
            }
        }
    }
    return $allTemplates;
}
 /**
  * Extract all of the keys that were assigned to an array variable.
  *
  * @param  array of Triumph_CallStack class the list to search in
  * @return array of string the array keys for the given
  *         array variable.
  */
 public function getArrayKeys($callStacks, $variableName)
 {
     $keys = array();
     foreach ($callStacks as $call) {
         if (Triumph_CallStack::ARRAY_KEY == $call->type && \opstring\compare($variableName, $call->destinationVariable) == 0) {
             $keys[$call->arrayKey] = 1;
         }
     }
     return array_keys($keys);
 }
示例#4
0
/**
 * Convenience function that checks whether haystack ends with needle. Comparison
 * is case-sensitive.
 *
 * @param $haystack the string to search in
 * @param $needle the string to search for
 * @return boolean TRUE if haystack begins with needle Examples:
 *         haystack: "combo box" needle: "box"
 *         haystack: "combo box" needle: "x"
 */
function ends_with($haystack, $needle)
{
    if (strlen($needle) > strlen($haystack)) {
        return FALSE;
    }
    $lastPiece = substr($haystack, strlen($haystack) - strlen($needle));
    return \opstring\compare($lastPiece, $needle) == 0;
}
/**
 * Resolves the given class name - method name pair into the URL.
 *
 * @param  array  $route the code igniter $routes array
 * @param  array  $config the code igniter $config array
 * @param  string $subDirectory  if non-empty means that the controller is in a sub-directory of application/controllers
 * @param  string $fileName the name of the controller file
 * @param  string $className the name of the controller class
 * @param  string $methodName the name of the method
 * @param  string $extra any extra segments to append to the URL
 * @return Triumph_Url the full URL after routing rules have been applied.
 */
function makeUrl($route, $config, $subDirectory, $fileName, $className, $methodName, $extra)
{
    // this function was taken from http://codeigniter.com/forums/viewthread/102438
    // with the following changes:
    // 1. including routes directly instead of using CI object
    //    as I was having problems including the bootstap file here
    $uri = '';
    if ($subDirectory) {
        $uri .= $subDirectory . '/';
    }
    $uri .= $className . '/' . $methodName;
    if ($extra) {
        $uri .= '/' . $extra;
    }
    // in case subdir has leading slash; routes usually don't
    $uri = ltrim($uri, '/');
    $uri = strtolower($uri);
    if (in_array($uri, $route)) {
        $uri = array_search($uri, $route);
    } else {
        foreach ($route as $singleRoute => $replace) {
            $singleRoute = preg_split('/(\\(.+?\\))/', $singleRoute, -1, PREG_SPLIT_DELIM_CAPTURE);
            $replace = preg_split('/(\\$\\d+)/', $replace, -1, PREG_SPLIT_DELIM_CAPTURE);
            if (count($singleRoute) != count($replace)) {
                continue;
            }
            $newroute = $newreplace = '';
            for ($i = 0; $i < count($singleRoute); $i++) {
                if ($i % 2) {
                    $newroute .= $replace[$i];
                    $newreplace .= $singleRoute[$i];
                } else {
                    $newroute .= $singleRoute[$i];
                    $newreplace .= $replace[$i];
                }
                $newreplace = str_replace(':any', '.+', str_replace(':num', '[0-9]+', $newreplace));
                if (preg_match("#^{$newreplace}\$#", $uri)) {
                    $uri = preg_replace("#^{$newreplace}\$#", $newroute, $uri);
                    break;
                }
            }
        }
    }
    if (0 == \opstring\compare('default_controller', $uri)) {
        $uri = '';
    }
    // respect the url suffix and index page from the config. for urls, make sure there is only one ending '/'
    // url already has leading slash
    // make sure url never has leading slash
    $indexPage = $config['index_page'];
    $indexPage = \opstring\ensure_ends_with($indexPage, '/');
    if (!empty($uri)) {
        $url = $indexPage . trim($uri . '/');
        $url = ltrim($url, '/');
    } else {
        $url = '';
    }
    if (isset($config['url_suffix']) && $config['url_suffix']) {
        $url .= $config['url_suffix'];
    }
    $triumphUrl = new Triumph_UrlTag($url, $fileName, $className, $methodName);
    return $triumphUrl;
}