public static function fileExport(array $addOn, DevHelper_Config_Base $config, $exportPath) { $list = array(); $classNameByAddOnId = self::getClassName($addOn['addon_id'], false, $config); $list['library'] = self::getClassNameInDirectory(XenForo_Autoloader::getInstance()->getRootDir(), $classNameByAddOnId, true); if (empty($list['library'])) { throw new XenForo_Exception(sprintf('`library` not found for %s', $addOn['addon_id'])); } $jsPath = self::getClassNameInDirectory(realpath(XenForo_Autoloader::getInstance()->getRootDir() . '/../js'), $classNameByAddOnId, true); if (!empty($jsPath)) { if (is_dir($jsPath)) { $list['js'] = $jsPath; } } $stylesDefaultPath = self::getClassNameInDirectory(realpath(XenForo_Autoloader::getInstance()->getRootDir() . '/../styles/default'), $classNameByAddOnId, true); if (!empty($stylesDefaultPath)) { if (is_dir($stylesDefaultPath)) { $list['styles_default'] = $stylesDefaultPath; } } $exportIncludes = $config->getExportIncludes(); foreach ($exportIncludes as $exportInclude) { $exportIncludePath = XenForo_Autoloader::getInstance()->getRootDir() . '/../' . $exportInclude; if (file_exists($exportIncludePath)) { $list[$exportInclude] = $exportIncludePath; } } // save add-on XML $xmlPath = self::getAddOnXmlPath($addOn, null, $config); /** @var XenForo_Model_AddOn $addOnModel */ $addOnModel = XenForo_Model::create('XenForo_Model_AddOn'); $addOnModel->getAddOnXml($addOn)->save($xmlPath); echo "Exported {$xmlPath} ({$addOn['version_string']}/{$addOn['version_id']})\n"; DevHelper_Helper_Phrase::parseXmlForPhraseTracking($xmlPath); $exportAddOns = $config->getExportAddOns(); foreach ($exportAddOns as $exportAddOnId) { $exportAddOn = $addOnModel->getAddOnById($exportAddOnId); if (empty($exportAddOn)) { die(sprintf("Could not find add-on %s\n", $exportAddOnId)); } $exportAddOnPath = self::getAddOnXmlPath($addOn, $exportAddOn, $config); $addOnModel->getAddOnXml($exportAddOn)->save($exportAddOnPath); echo "Exported {$exportAddOnPath} ({$exportAddOn['version_string']}/{$exportAddOn['version_id']})\n"; } $exportStyles = $config->getExportStyles(); if (!empty($exportStyles)) { /** @var XenForo_Model_Style $styleModel */ $styleModel = $addOnModel->getModelFromCache('XenForo_Model_Style'); $styles = $styleModel->getAllStyles(); $exportedStyleCount = 0; foreach ($styles as $style) { if (in_array($style['title'], $exportStyles, true)) { $stylePath = self::getStyleXmlPath($addOn, $style, $config); $styleModel->getStyleXml($style)->save($stylePath); echo "Exported {$stylePath}\n"; $exportedStyleCount++; } } if ($exportedStyleCount < count($exportStyles)) { die("Not all export styles could be found...\n"); } } // generate hashes self::generateHashesFile($addOn, $config, $list); // check for file_health_check event listener /** @var XenForo_Model_CodeEvent $codeEventModel */ $codeEventModel = XenForo_Model::create('XenForo_Model_CodeEvent'); $addOnEventListeners = $codeEventModel->getEventListenersByAddOn($addOn['addon_id']); $fileHealthCheckFound = false; foreach ($addOnEventListeners as $addOnEventListener) { if ($addOnEventListener['event_id'] === 'file_health_check') { $fileHealthCheckFound = true; } if (!is_callable(array($addOnEventListener['callback_class'], $addOnEventListener['callback_method']))) { die(sprintf("Callback is not callable %s::%s\n", $addOnEventListener['callback_class'], $addOnEventListener['callback_method'])); } } if (!$fileHealthCheckFound) { // try to generate the file health check event listener ourselves if (DevHelper_Generator_Code_Listener::generateFileHealthCheck($addOn, $config)) { $fileHealthCheckFound = true; } } if (!$fileHealthCheckFound) { die("No `file_health_check` event listener found.\n"); } /** @var XenForo_Application $application */ $application = XenForo_Application::getInstance(); $rootPath = realpath($application->getRootDir()); if (strpos($exportPath, 'upload') === false) { $exportPath .= '/upload'; } XenForo_Helper_File::createDirectory($exportPath); $exportPath = realpath($exportPath); $options = array('extensions' => array('php', 'inc', 'txt', 'xml', 'htm', 'html', 'js', 'css', 'jpg', 'jpeg', 'png', 'gif', 'swf', 'crt', 'pem', 'eot', 'svg', 'ttf', 'woff', 'woff2', 'otf', 'md'), 'filenames_lowercase' => array('license', 'readme', 'copyright', '.htaccess', 'changelog', 'composer.json', 'readme.rdoc', 'version'), 'force' => true, 'addon_id' => $addOn['addon_id'], 'excludes' => array(), 'excludeRegExs' => array()); $excludes = $config->getExportExcludes(); foreach ($excludes as $exclude) { if (preg_match('/^#.+#$/', $exclude)) { $options['excludeRegExs'][] = $exclude; } else { $options['excludes'][] = $exclude; } } foreach ($list as $type => $entry) { self::_fileExport($entry, $exportPath, $rootPath, $options); } // copy one xml copy to the export directory directory $xmlCopyPath = sprintf('%s/%s', dirname($exportPath), basename($xmlPath)); if (@copy($xmlPath, $xmlCopyPath)) { echo "Copied {$xmlPath} -> {$xmlCopyPath}\n"; } else { echo "Can't cp {$xmlPath} -> {$xmlCopyPath}\n"; } }