/** * find the value in the project configuration (e.g the version) * @param string $name the name of the config to get */ public function projectConfig($name) { if (isset($this->projectConfig)) { return $this->projectConfig->get($name); } else { return null; } }
/** * Resolves the path to the source template file of the backend * @return string Absolute path to template file */ public function getTemplateFileContents($filename) { $filepath = realpath(rtrim($this->config->get('templatepath', 'backend'), '/') . '/' . $this->name . '/' . $filename); if (!file_exists($filepath)) { $filepath = realpath(__DIR__ . '/../templates/' . $this->name . '/' . $filename); } return file_get_contents($filepath); }
/** * Shows an exception opening the file and highlighting the wrong part * * @param \Exception $e * @param Config $config */ protected static function showException(\Exception $e, Config $config = null) { echo get_class($e), ': ', $e->getMessage(), PHP_EOL; if (method_exists($e, 'getExtra')) { $extra = $e->getExtra(); if (is_array($extra)) { if (isset($extra['file'])) { echo PHP_EOL; $lines = file($extra['file']); if (isset($lines[$extra['line'] - 1])) { $line = $lines[$extra['line'] - 1]; echo "\t", str_replace("\t", " ", $line); if ($extra['char'] - 1 > 0) { echo "\t", str_repeat("-", $extra['char'] - 1), "^", PHP_EOL; } } } } } echo PHP_EOL; if ($config && $config->get('verbose')) { echo 'at ', str_replace(ZEPHIRPATH, '', $e->getFile()), '(', $e->getLine(), ')', PHP_EOL; echo str_replace(ZEPHIRPATH, '', $e->getTraceAsString()), PHP_EOL; } exit(1); }
/** * Generates stubs * * @param string $path */ public function generate($path) { $namespace = $this->config->get('namespace'); foreach ($this->files as $file) { $class = $file->getClassDefinition(); $source = $this->buildClass($class); $filename = ucfirst($class->getName()) . '.zep.php'; $filePath = $path . str_replace($namespace, '', str_replace($namespace . '\\\\', DIRECTORY_SEPARATOR, strtolower($class->getNamespace()))); $filePath = str_replace('\\', DIRECTORY_SEPARATOR, $filePath); $filePath = str_replace(DIRECTORY_SEPARATOR . DIRECTORY_SEPARATOR, DIRECTORY_SEPARATOR, $filePath); if (!is_dir($filePath)) { mkdir($filePath, 0777, true); } $filePath = realpath($filePath) . '/'; file_put_contents($filePath . $filename, $source); } }
/** * Generate package-dependencies config for m4 * * @param $contentM4 * @throws Exception * @return string * TODO: Move the template depending part to backend? */ public function generatePackageDependenciesM4($contentM4) { $templatePath = $this->backend->getInternalTemplatePath(); $packageDependencies = $this->config->get('package-dependencies'); if (is_array($packageDependencies)) { $pkgconfigM4 = file_get_contents($templatePath . '/pkg-config.m4'); $pkgconfigCheckM4 = file_get_contents($templatePath . '/pkg-config-check.m4'); $extraCFlags = ''; foreach ($packageDependencies as $pkg => $version) { $pkgM4Buf = $pkgconfigCheckM4; $operator = '='; $operatorCmd = '--exact-version'; $ar = explode("=", $version); if (count($ar) == 1) { if ($version == '*') { $version = '0.0.0'; $operator = '>='; $operatorCmd = '--atleast-version'; } } else { switch ($ar[0]) { default: $version = trim($ar[1]); break; case '<': $operator = '<='; $operatorCmd = '--max-version'; $version = trim($ar[1]); break; case '>': $operator = '>='; $operatorCmd = '--atleast-version'; $version = trim($ar[1]); break; } } $toReplace = array('%PACKAGE_LOWER%' => strtolower($pkg), '%PACKAGE_UPPER%' => strtoupper($pkg), '%PACKAGE_REQUESTED_VERSION%' => $operator . ' ' . $version, '%PACKAGE_PKG_CONFIG_COMPARE_VERSION%' => $operatorCmd . '=' . $version); foreach ($toReplace as $mark => $replace) { $pkgM4Buf = str_replace($mark, $replace, $pkgM4Buf); } $pkgconfigM4 .= $pkgM4Buf; $extraCFlags .= '$PHP_' . strtoupper($pkg) . '_INCS '; } $contentM4 = str_replace('%PROJECT_EXTRA_CFLAGS%', '%PROJECT_EXTRA_CFLAGS% ' . $extraCFlags, $contentM4); $contentM4 = str_replace('%PROJECT_PACKAGE_DEPENDENCIES%', $pkgconfigM4, $contentM4); return $contentM4; } $contentM4 = str_replace('%PROJECT_PACKAGE_DEPENDENCIES%', '', $contentM4); return $contentM4; }
public function testSetWithNamespace() { $config = new Config(); $config->set('unused-variable', false, 'warnings'); $this->assertFalse($config->get('unused-variable', 'warnings')); }
/** * Find the theme directory depending on the command line options and the config. * * theme directory is checked in this order : * => check if the command line argument --theme-path was given * => if not ; find the different theme directories on the config $config['api']['theme-directories'] * search the theme from the name ($config['api']['theme']['name'] in the theme directories, * if nothing was found, we look in the zephir install dir default themes (templates/Api/themes) * * @param $themeConfig * @param Config $config * @param CommandInterface $command * @return null|string * @throws ConfigException * @throws Exception */ private function __findThemeDirectory($themeConfig, Config $config, CommandInterface $command) { // check if there are additional theme paths in the config $themeDirectoriesConfig = $config->get("theme-directories", "api"); if ($themeDirectoriesConfig) { if (is_array($themeDirectoriesConfig)) { $themesDirectories = $themeDirectoriesConfig; } else { throw new ConfigException("invalid value for theme config 'theme-directories'"); } } else { $themesDirectories = array(); } $themesDirectories[] = ZEPHIRPATH . "templates/Api/themes"; $this->themesDirectories = $themesDirectories; // check if the path was set from the command $themePath = $command->getParameter("theme-path"); if (null !== $themePath) { if (file_exists($themePath) && is_dir($themePath)) { return $themePath; } else { throw new Exception("Invalid value for option 'theme-path' : the theme '{$themePath}' was not found or is not a valid theme."); } } if (!isset($themeConfig["name"]) || !$themeConfig["name"]) { throw new ConfigException("There is no theme neither in the the theme config nor as a command line argument"); } return $this->findThemePathByName($themeConfig["name"]); }
/** * Create project.c and project.h by compiled files to test extension * * @param string $project * * @throws Exception * @return boolean */ public function createProjectFiles($project) { $needConfigure = $this->checkKernelFiles(); /** * project.c */ $content = file_get_contents(__DIR__ . '/../templates/project.c'); if (empty($content)) { throw new Exception("Template project.c doesn't exist"); } $files = $this->files; /** * Round 1. Calculate the dependency rank * Classes are ordered according to a dependency ranking * Classes that are dependencies of classes that are dependency of other classes * have more weight */ foreach ($files as $file) { $classDefinition = $file->getClassDefinition(); if ($classDefinition) { $classDefinition->calculateDependencyRank(); } } /** * Round 1.5 Make a second pass to ensure classes will have the correct weight */ foreach ($files as $file) { $classDefinition = $file->getClassDefinition(); if ($classDefinition) { $classDefinition->calculateDependencyRank(); } } $classEntries = array(); $classInits = array(); $interfaceEntries = array(); $interfaceInits = array(); /** * Round 2. Generate the ZEPHIR_INIT calls according to the dependency rank */ foreach ($files as $file) { $classDefinition = $file->getClassDefinition(); if ($classDefinition) { $dependencyRank = $classDefinition->getDependencyRank(); if ($classDefinition->getType() == 'class') { if (!isset($classInits[$dependencyRank])) { $classEntries[$dependencyRank] = array(); $classInits[$dependencyRank] = array(); } $classEntries[$dependencyRank][] = 'zend_class_entry *' . $classDefinition->getClassEntry() . ';'; $classInits[$dependencyRank][] = 'ZEPHIR_INIT(' . $classDefinition->getCNamespace() . '_' . $classDefinition->getName() . ');'; } else { if (!isset($interfaceInits[$dependencyRank])) { $interfaceEntries[$dependencyRank] = array(); $interfaceInits[$dependencyRank] = array(); } $interfaceEntries[$dependencyRank][] = 'zend_class_entry *' . $classDefinition->getClassEntry() . ';'; $interfaceInits[$dependencyRank][] = 'ZEPHIR_INIT(' . $classDefinition->getCNamespace() . '_' . $classDefinition->getName() . ');'; } } } krsort($classInits); krsort($classEntries); krsort($interfaceInits); krsort($interfaceEntries); $completeInterfaceInits = array(); foreach ($interfaceInits as $rankInterfaceInits) { asort($rankInterfaceInits, SORT_STRING); $completeInterfaceInits = array_merge($completeInterfaceInits, $rankInterfaceInits); } $completeInterfaceEntries = array(); foreach ($interfaceEntries as $rankInterfaceEntries) { asort($rankInterfaceEntries, SORT_STRING); $completeInterfaceEntries = array_merge($completeInterfaceEntries, $rankInterfaceEntries); } $completeClassInits = array(); foreach ($classInits as $rankClassInits) { asort($rankClassInits, SORT_STRING); $completeClassInits = array_merge($completeClassInits, $rankClassInits); } $completeClassEntries = array(); foreach ($classEntries as $rankClassEntries) { asort($rankClassEntries, SORT_STRING); $completeClassEntries = array_merge($completeClassEntries, $rankClassEntries); } /** * Round 3. Process extension globals */ list($globalCode, $globalStruct, $globalsDefault) = $this->processExtensionGlobals($project); if ($project == 'zend') { $safeProject = 'zend_'; } else { $safeProject = $project; } /** * Round 4. Process extension info */ $phpInfo = $this->processExtensionInfo(); $toReplace = array('%PROJECT_LOWER_SAFE%' => strtolower($safeProject), '%PROJECT_LOWER%' => strtolower($project), '%PROJECT_UPPER%' => strtoupper($project), '%PROJECT_CAMELIZE%' => ucfirst($project), '%CLASS_ENTRIES%' => implode(PHP_EOL, array_merge($completeInterfaceEntries, $completeClassEntries)), '%CLASS_INITS%' => implode(PHP_EOL . "\t", array_merge($completeInterfaceInits, $completeClassInits)), '%INIT_GLOBALS%' => $globalsDefault, '%EXTENSION_INFO%' => $phpInfo); foreach ($toReplace as $mark => $replace) { $content = str_replace($mark, $replace, $content); } /** * Round 5. Generate and place the entry point of the project */ Utils::checkAndWriteIfNeeded($content, 'ext/' . $safeProject . '.c'); unset($content); /** * Round 6. Generate the project main header */ $content = file_get_contents(__DIR__ . '/../templates/project.h'); if (empty($content)) { throw new Exception("Template project.h doesn't exists"); } $includeHeaders = array(); foreach ($this->compiledFiles as $file) { if ($file) { $fileH = str_replace(".c", ".zep.h", $file); $include = '#include "' . $fileH . '"'; $includeHeaders[] = $include; } } $toReplace = array('%INCLUDE_HEADERS%' => implode(PHP_EOL, $includeHeaders)); foreach ($toReplace as $mark => $replace) { $content = str_replace($mark, $replace, $content); } Utils::checkAndWriteIfNeeded($content, 'ext/' . $safeProject . '.h'); unset($content); /** * Round 7. Create php_project.h */ $content = file_get_contents(__DIR__ . '/../templates/php_project.h'); if (empty($content)) { throw new Exception('Template php_project.h doesn`t exist'); } $toReplace = array('%PROJECT_LOWER_SAFE%' => strtolower($safeProject), '%PROJECT_LOWER%' => strtolower($project), '%PROJECT_UPPER%' => strtoupper($project), '%PROJECT_EXTNAME%' => strtolower($project), '%PROJECT_NAME%' => utf8_decode($this->config->get('name')), '%PROJECT_AUTHOR%' => utf8_decode($this->config->get('author')), '%PROJECT_VERSION%' => utf8_decode($this->config->get('version')), '%PROJECT_DESCRIPTION%' => utf8_decode($this->config->get('description')), '%PROJECT_ZEPVERSION%' => self::VERSION, '%EXTENSION_GLOBALS%' => $globalCode, '%EXTENSION_STRUCT_GLOBALS%' => $globalStruct); foreach ($toReplace as $mark => $replace) { $content = str_replace($mark, $replace, $content); } Utils::checkAndWriteIfNeeded($content, 'ext/php_' . $safeProject . '.h'); unset($content); return $needConfigure; }
/** * Find the theme directory depending on the command line options and the config. * * theme directory is checked in this order : * => check if the command line argument --theme-path was given * => if not ; find the different theme directories on the config $config['api']['theme-directories'] * search the theme from the name ($config['api']['theme']['name'] in the theme directories, * if nothing was found, we look in the zephir install dir default themes (templates/Api/themes) * * @param $themeConfig * @param Config $config * @param CommandInterface $command * @return null|string * @throws ConfigException * @throws Exception */ private function __findThemeDirectory($themeConfig, Config $config, CommandInterface $command) { // check if the path was set from the command $themePath = $command->getParameter("theme-path"); if (null !== $themePath) { if (file_exists($themePath) && is_dir($themePath)) { return $themePath; } else { throw new Exception("Invalid value for option 'theme-path' : the theme '{$themePath}' was not found or is not a valid theme."); } } // check the theme from the config // check if there are additional theme paths in the config $themeDirectoriesConfig = $config->get("theme-directories", "api"); if ($themeDirectoriesConfig) { if (is_array($themeDirectoriesConfig)) { $themesDirectories = $themeDirectoriesConfig; } else { throw new ConfigException("invalid value for theme config 'theme-directories'"); } } else { $themesDirectories = array(); } $themesDirectories[] = ZEPHIRPATH . "templates/Api/themes"; $path = null; foreach ($themesDirectories as $themeDir) { $dir = rtrim($themeDir, "/") . "/"; $path = realpath($dir . $themeConfig["name"]); if ($path) { break; } } return $path; }