Zephir\Compiler::createProjectFiles PHP Method

createProjectFiles() public method

Create project.c and project.h according to the current extension
public createProjectFiles ( string $project ) : boolean
$project string
return boolean TODO: Move the part of the logic which depends on templates (backend-specific) to backend?
    public function createProjectFiles($project)
    {
        $needConfigure = $this->checkKernelFiles();
        /**
         * project.c
         */
        $content = $this->backend->getTemplateFileContents('project.c');
        if (empty($content)) {
            throw new Exception("Template project.c doesn't exist");
        }
        $includes = '';
        $destructors = '';
        $files = array_merge($this->files, $this->anonymousFiles);
        /**
         * Round 1. Calculate the dependency rank
         */
        $this->calculateDependencies($files);
        $classEntries = array();
        $classInits = array();
        $interfaceEntries = array();
        $interfaceInits = array();
        /**
         * Round 2. Generate the ZEPHIR_INIT calls according to the dependency rank
         */
        foreach ($files as $file) {
            /** @var \Zephir\Compiler\FileInterface $file */
            if (!$file->isExternal()) {
                $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, $initEntries) = $this->processExtensionGlobals($project);
        if ($project == 'zend') {
            $safeProject = 'zend_';
        } else {
            $safeProject = $project;
        }
        /**
         * Round 4. Process extension info
         */
        $phpInfo = $this->processExtensionInfo();
        /**
         * Round 5. Generate Function entries (FE)
         */
        list($feHeader, $feEntries) = $this->generateFunctionInformation();
        /**
         * Check if there are module/request/global destructors
         */
        $destructors = $this->config->get('destructors');
        if (is_array($destructors)) {
            $invokeDestructors = $this->processCodeInjection($destructors);
            $includes = $invokeDestructors[0];
            $destructors = $invokeDestructors[1];
        }
        /**
         * Check if there are module/request/global initializers
         */
        $initializers = $this->config->get('initializers');
        if (is_array($initializers)) {
            $invokeInitializers = $this->processCodeInjection($initializers);
            $includes = $invokeInitializers[0];
            $initializers = $invokeInitializers[1];
        }
        /**
         * Append extra details
         */
        $extraClasses = $this->config->get('extra-classes');
        if (is_array($extraClasses)) {
            foreach ($extraClasses as $value) {
                if (isset($value['init'])) {
                    $completeClassInits[] = 'ZEPHIR_INIT(' . $value['init'] . ')';
                }
                if (isset($value['entry'])) {
                    $completeClassEntries[] = 'zend_class_entry *' . $value['entry'] . ';';
                }
            }
        }
        $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[0], '%INIT_MODULE_GLOBALS%' => $globalsDefault[1], '%EXTENSION_INFO%' => $phpInfo, '%EXTRA_INCLUDES%' => $includes, '%DESTRUCTORS%' => $destructors, '%INITIALIZERS%' => implode(PHP_EOL, array_merge($this->internalInitializers, array($initializers))), '%FE_HEADER%' => $feHeader, '%FE_ENTRIES%' => $feEntries, '%PROJECT_INI_ENTRIES%' => implode(PHP_EOL . "\t", $initEntries));
        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 = $this->backend->getTemplateFileContents('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;
            }
        }
        /**
         * Append extra headers
         */
        $extraClasses = $this->config->get('extra-classes');
        if (is_array($extraClasses)) {
            foreach ($extraClasses as $value) {
                if (isset($value['header'])) {
                    $include = '#include "' . $value['header'] . '"';
                    $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 = $this->backend->getTemplateFileContents('php_project.h');
        if (empty($content)) {
            throw new Exception("Template php_project.h doesn't exist");
        }
        $version = self::getCurrentVersion();
        $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%' => $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;
    }