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;
}