示例#1
0
 /**
  * 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);
 }
示例#2
0
文件: Template.php 项目: edin/zephir
 /**
  * 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;
     }
 }
示例#3
0
 /**
  * Test saveOnExit method.
  */
 public function testSaveOnExit()
 {
     chdir(sys_get_temp_dir());
     $config = new Config();
     $config->set('name', 'foo');
     $config->saveOnExit();
     $configJson = json_decode(file_get_contents('config.json'), true);
     $this->assertInternalType('array', $configJson);
     $this->assertSame($configJson['name'], 'foo');
     $this->cleanTmpConfigFile();
 }
示例#4
0
 /**
  * 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);
     }
 }
示例#5
0
 /**
  * @param string $zephirCode
  *
  * @throws \Exception
  */
 public function isValid($namespace)
 {
     if (!defined('ZEPHIRPATH')) {
         define('ZEPHIRPATH', realpath(__DIR__ . '/../../vendor/phalcon/zephir') . '/');
     }
     $generateCommand = new CommandGenerate();
     $cleanCommand = new CommandFullClean();
     try {
         $config = new Config();
         $config->set('namespace', $namespace);
         $config->set('silent', true);
         $cleanCommand->execute($config, new ZephirLogger($config));
         $generateCommand->execute($config, new ZephirLogger($config));
     } catch (CompilerException $e) {
         throw new \Exception(sprintf('Error on %s', $e->getMessage()));
     }
     return true;
 }
 /**
  * Build a zephir extension and return the extension path
  *
  * @param string  $zephir
  * @param boolean $silent
  * @throws \Exception
  * @return string
  */
 public function build($zephir, $silent)
 {
     $dto = $this->zephirClassInfo->getZephirCodeInfo($zephir);
     $this->fileWorker->writeZephirFile($dto, $zephir);
     $this->defineZephirHome();
     try {
         $config = new Config();
         $config->set('namespace', $dto->getExtensionName());
         $config->set('silent', $silent);
         if (is_dir('ext')) {
             $this->commandFullClean->execute($config, new ZephirLogger($config));
         }
         $this->commandBuild->execute($config, new ZephirLogger($config));
     } catch (\Exception $e) {
         $this->fileWorker->rmdirRecursive($dto->getBaseDir());
         throw new \Exception(sprintf('Error on %s', $e->getMessage()));
     }
     return 'ext/modules/' . $dto->getExtensionName() . '.so';
 }
示例#7
0
 /**
  * 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;
 }
 /**
  * @param string $zephirCode
  *
  * @throws \Exception
  */
 public function isValid($namespace)
 {
     $currentDir = getcwd();
     chdir(FileWriter::BASE_DESTINATION . $namespace);
     if (!defined('ZEPHIRPATH')) {
         define('ZEPHIRPATH', realpath(__DIR__ . '/../../vendor/phalcon/zephir') . '/');
     }
     $generateCommand = new CommandGenerate();
     $cleanCommand = new CommandFullClean();
     try {
         $config = new Config();
         $config->set('namespace', strtolower($namespace));
         $config->set('silent', true);
         if (is_dir('ext')) {
             $cleanCommand->execute($config, new ZephirLogger($config));
         }
         $generateCommand->execute($config, new ZephirLogger($config));
     } catch (Exception $e) {
         chdir($currentDir);
         throw new \Exception(sprintf('Error on %s', $e->getMessage()));
     }
     chdir($currentDir);
     return true;
 }
示例#9
0
 public function testSetWithNamespace()
 {
     $config = new Config();
     $config->set('unused-variable', false, 'warnings');
     $this->assertFalse($config->get('unused-variable', 'warnings'));
 }
示例#10
0
 /**
  * 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"]);
 }
示例#11
0
 /**
  * Boots the compiler executing the specified action
  */
 public static function boot()
 {
     try {
         /**
          * Global config
          */
         $config = new Config();
         register_shutdown_function(array($config, 'saveOnExit'));
         /**
          * Global logger
          */
         $logger = new Logger($config);
         if (isset($_SERVER['argv'][1])) {
             $action = $_SERVER['argv'][1];
         } else {
             $action = 'help';
         }
         /**
          * Change configurations flags
          */
         if ($_SERVER['argc'] >= 2) {
             for ($i = 2; $i < $_SERVER['argc']; $i++) {
                 $parameter = $_SERVER['argv'][$i];
                 if (preg_match('/^-fno-([a-z0-9\\-]+)$/', $parameter, $matches)) {
                     $config->set($matches[1], false, 'optimizations');
                     continue;
                 }
                 if (preg_match('/^-f([a-z0-9\\-]+)$/', $parameter, $matches)) {
                     $config->set($matches[1], true, 'optimizations');
                 }
                 if (preg_match('/^-W([a-z0-9\\-]+)$/', $parameter, $matches)) {
                     $logger->set($matches[1], false, 'warnings');
                     continue;
                 }
                 if (preg_match('/^-w([a-z0-9\\-]+)$/', $parameter, $matches)) {
                     $logger->set($matches[1], true, 'warnings');
                     continue;
                 }
                 if (preg_match('/^--([a-z0-9\\-]+)$/', $parameter, $matches)) {
                     $config->set($matches[1], true, 'extra');
                     continue;
                 }
                 if (preg_match('/^--([a-z0-9\\-]+)=(.*)$/', $parameter, $matches)) {
                     $config->set($matches[1], $matches[2], 'extra');
                     continue;
                 }
                 switch ($parameter) {
                     case '-w':
                         $config->set('silent', true);
                         break;
                     case '-v':
                         $config->set('verbose', true);
                         break;
                     case '-V':
                         $config->set('verbose', false);
                         break;
                     default:
                         break;
                 }
             }
         }
         /**
          * Register built-in commands
          * @var $item \DirectoryIterator
          */
         foreach (new \DirectoryIterator(ZEPHIRPATH . 'Library/Commands') as $item) {
             if (!$item->isDir()) {
                 $className = 'Zephir\\Commands\\' . str_replace('.php', '', $item->getBaseName());
                 $class = new \ReflectionClass($className);
                 if (!$class->isAbstract() && !$class->isInterface()) {
                     /**
                      * @var $command CommandAbstract
                      */
                     $command = new $className();
                     if (!$command instanceof CommandAbstract) {
                         throw new \Exception('Class ' . $class->name . ' must be instance of CommandAbstract');
                     }
                     self::$commands[$command->getCommand()] = $command;
                 }
             }
         }
         if (!isset(self::$commands[$action])) {
             $message = 'Unrecognized action "' . $action . '"';
             $metaphone = metaphone($action);
             foreach (self::$commands as $key => $command) {
                 if (metaphone($key) == $metaphone) {
                     $message .= PHP_EOL . PHP_EOL . 'Did you mean "' . $key . '"?';
                 }
             }
             throw new \Exception($message);
         }
         /**
          * Execute the command
          */
         self::$commands[$action]->execute($config, $logger);
     } catch (\Exception $e) {
         self::showException($e, isset($config) ? $config : null);
     }
 }
示例#12
0
 /**
  * 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;
 }
示例#13
0
 /**
  * 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;
 }