/** * @see \wcf\system\cache\builder\AbstractCacheBuilder::rebuild() */ public function rebuild(array $parameters) { $data = array('abbreviation' => array(), 'application' => array(), 'primary' => 0, 'wcf' => null); // fetch applications $applicationList = new ApplicationList(); $applicationList->readObjects(); $applications = $applicationList->getObjects(); foreach ($applications as $application) { $data['application'][$application->packageID] = $application; // save primary application's package id if ($application->isPrimary) { $data['primary'] = $application->packageID; } } // fetch abbreviations $packageList = new PackageList(); $packageList->getConditionBuilder()->add('package.isApplication = ?', array(1)); $packageList->readObjects(); foreach ($packageList->getObjects() as $package) { $data['abbreviation'][Package::getAbbreviation($package->package)] = $package->packageID; } // assign wcf pseudo-application if (PACKAGE_ID) { $data['wcf'] = $data['application'][1]; unset($data['application'][1]); } return $data; }
/** * @see \wcf\system\cache\builder\AbstractCacheBuilder::rebuild() */ public function rebuild(array $parameters) { $data = array(); $isACP = $parameters['environment'] == 'admin'; $packageList = new PackageList(); $packageList->getConditionBuilder()->add("isApplication = ?", array(1)); $packageList->readObjects(); foreach ($packageList as $package) { $abbreviation = Package::getAbbreviation($package->package); $path = WCF_DIR . $package->packageDir . 'lib/' . ($isACP ? 'acp/' : ''); $data[$abbreviation] = array('action' => $this->getControllers($path, $abbreviation, 'action', $isACP), 'form' => $this->getControllers($path, $abbreviation, 'form', $isACP), 'page' => $this->getControllers($path, $abbreviation, 'page', $isACP)); } return $data; }
/** * @see \wcf\system\package\plugin\IPackageInstallationPlugin::install() */ public function install() { parent::install(); // extract sql file from archive if ($queries = $this->getSQL($this->instruction['value'])) { $package = $this->installation->getPackage(); // replace app1_ with app{WCF_N}_ in the table names for // all applications $packageList = new PackageList(); $packageList->getConditionBuilder()->add('package.isApplication = ?', array(1)); $packageList->readObjects(); foreach ($packageList as $package) { $abbreviation = Package::getAbbreviation($package->package); $queries = str_replace($abbreviation . '1_', $abbreviation . WCF_N . '_', $queries); } // check queries $parser = new PackageInstallationSQLParser($queries, $this->installation->getPackage(), $this->installation->getAction()); $conflicts = $parser->test(); if (!empty($conflicts) && (isset($conflicts['CREATE TABLE']) || isset($conflicts['DROP TABLE']))) { $unknownCreateTable = isset($conflicts['CREATE TABLE']) ? $conflicts['CREATE TABLE'] : array(); $unknownDropTable = isset($conflicts['DROP TABLE']) ? $conflicts['DROP TABLE'] : array(); $errorMessage = "Can't"; if (!empty($unknownDropTable)) { $errorMessage .= " drop unknown table"; if (count($unknownDropTable) > 1) { $errorMessage .= "s"; } $errorMessage .= " '" . implode("', '", $unknownDropTable) . "'"; } if (!empty($unknownCreateTable)) { if (!empty($unknownDropTable)) { $errorMessage .= " and can't"; } $errorMessage .= " overwrite unknown table"; if (count($unknownCreateTable) > 1) { $errorMessage .= "s"; } $errorMessage .= " '" . implode("', '", $unknownCreateTable) . "'"; } throw new SystemException($errorMessage); } // execute queries $parser->execute(); // log changes $parser->log(); } }
/** * Returns the directory of the application with the given abbrevation. * * @param string $abbreviation * @return string */ public static function getDirectory($abbreviation) { if (static::$directories === null) { static::$directories = array(); // read application directories $packageList = new PackageList(); $packageList->getConditionBuilder()->add('package.isApplication = ?', array(1)); $packageList->readObjects(); foreach ($packageList as $package) { $abbr = Package::getAbbreviation($package->package); static::$directories[$abbr] = FileUtil::addTrailingSlash(FileUtil::getRealPath(WCF_DIR . $package->packageDir)); } } if (!isset(static::$directories[$abbreviation])) { throw new SystemException("Unknown application '" . $abbreviation . "'"); } return static::$directories[$abbreviation]; }
/** * @see \wcf\system\package\plugin\IPackageInstallationPlugin::install() */ public function install() { parent::install(); $abbreviation = 'wcf'; if (isset($this->instruction['attributes']['application'])) { $abbreviation = $this->instruction['attributes']['application']; } else { if ($this->installation->getPackage()->isApplication) { $abbreviation = Package::getAbbreviation($this->installation->getPackage()->package); } } // absolute path to package dir $packageDir = Application::getDirectory($abbreviation); // extract files.tar to temp folder $sourceFile = $this->installation->getArchive()->extractTar($this->instruction['value'], 'templates_'); // create file handler $fileHandler = new TemplatesFileHandler($this->installation, $abbreviation); $this->installation->extractFiles($packageDir . 'templates/', $sourceFile, $fileHandler); // delete temporary sourceArchive @unlink($sourceFile); }
/** * @see wcf\system\cache\ICacheBuilder::getData() */ public function getData(array $cacheResource) { list($cache, $packageID) = explode('-', $cacheResource['cache']); $data = array('abbreviation' => array(), 'application' => array(), 'group' => null, 'primary' => 0, 'wcf' => null); // lookup group id for currently active application $sql = "SELECT\tgroupID\n\t\t\tFROM\twcf" . WCF_N . "_application\n\t\t\tWHERE\tpackageID = ?"; $statement = WCF::getDB()->prepareStatement($sql); $statement->execute(array($packageID)); $row = $statement->fetchArray(); // current application is not part of an application group if (!$row || $row['groupID'] == 0 || $row['groupID'] === null) { $data['application'] = array($packageID => new application\Application($packageID)); } else { // fetch applications $applicationList = new application\ApplicationList(); $applicationList->getConditionBuilder()->add("application.groupID = ?", array($row['groupID'])); $applicationList->sqlLimit = 0; $applicationList->readObjects(); $applications = $applicationList->getObjects(); foreach ($applications as $application) { $data['application'][$application->packageID] = $application; // save primary application's package id if ($application->isPrimary) { $data['primary'] = $application->packageID; } } // fetch application group $data['group'] = new ApplicationGroup($row['groupID']); } // fetch abbreviations $packageList = new PackageList(); $packageList->getConditionBuilder()->add('packageID IN (?)', array(array_keys($data['application']))); $packageList->readObjects(); foreach ($packageList->getObjects() as $package) { $data['abbreviation'][Package::getAbbreviation($package->package)] = $package->packageID; } // fetch wcf pseudo-application $data['wcf'] = new application\Application(1); return $data; }
/** * @see \wcf\system\package\plugin\IPackageInstallationPlugin::install() */ public function install() { parent::install(); $abbreviation = 'wcf'; if (isset($this->instruction['attributes']['application'])) { $abbreviation = $this->instruction['attributes']['application']; } else { if ($this->installation->getPackage()->isApplication) { $abbreviation = Package::getAbbreviation($this->installation->getPackage()->package); } } // absolute path to package dir $packageDir = Application::getDirectory($abbreviation); // extract files.tar to temp folder $sourceFile = $this->installation->getArchive()->extractTar($this->instruction['value'], 'files_'); // create file handler $fileHandler = new FilesFileHandler($this->installation, $abbreviation); // extract content of files.tar $fileInstaller = $this->installation->extractFiles($packageDir, $sourceFile, $fileHandler); // if this a an application, write config.inc.php for this package if ($this->installation->getPackage()->isApplication == 1 && $this->installation->getPackage()->package != 'com.woltlab.wcf' && $this->installation->getAction() == 'install' && $abbreviation != 'wcf') { // touch file $fileInstaller->touchFile(PackageInstallationDispatcher::CONFIG_FILE); // create file Package::writeConfigFile($this->installation->getPackageID()); // log file $sql = "INSERT INTO\twcf" . WCF_N . "_package_installation_file_log\n\t\t\t\t\t\t(packageID, filename, application)\n\t\t\t\tVALUES\t\t(?, ?, ?)"; $statement = WCF::getDB()->prepareStatement($sql); $statement->execute(array($this->installation->getPackageID(), 'config.inc.php', Package::getAbbreviation($this->installation->getPackage()->package))); // load application WCF::loadRuntimeApplication($this->installation->getPackageID()); } // delete temporary sourceArchive @unlink($sourceFile); // update acp style file StyleUtil::updateStyleFile(); }
/** * Imports a style. * * @param string $filename * @param integer $packageID * @param StyleEditor $style * @return StyleEditor */ public static function import($filename, $packageID = 1, StyleEditor $style = null) { // open file $tar = new Tar($filename); // get style data $data = self::readStyleData($tar); $styleData = array('styleName' => $data['name'], 'variables' => $data['variables'], 'styleVersion' => $data['version'], 'styleDate' => $data['date'], 'copyright' => $data['copyright'], 'license' => $data['license'], 'authorName' => $data['authorName'], 'authorURL' => $data['authorURL']); // create template group if (!empty($data['templates'])) { $templateGroupName = $originalTemplateGroupName = $data['name']; $templateGroupFolderName = preg_replace('/[^a-z0-9_-]/i', '', $templateGroupName); if (empty($templateGroupFolderName)) { $templateGroupFolderName = 'generic' . mb_substr(StringUtil::getRandomID(), 0, 8); } $originalTemplateGroupFolderName = $templateGroupFolderName; // get unique template group name $i = 1; while (true) { $sql = "SELECT\tCOUNT(*) AS count\n\t\t\t\t\tFROM\twcf" . WCF_N . "_template_group\n\t\t\t\t\tWHERE\ttemplateGroupName = ?"; $statement = WCF::getDB()->prepareStatement($sql); $statement->execute(array($templateGroupName)); $row = $statement->fetchArray(); if (!$row['count']) { break; } $templateGroupName = $originalTemplateGroupName . '_' . $i; $i++; } // get unique folder name $i = 1; while (true) { $sql = "SELECT\tCOUNT(*) AS count\n\t\t\t\t\tFROM\twcf" . WCF_N . "_template_group\n\t\t\t\t\tWHERE\ttemplateGroupFolderName = ?"; $statement = WCF::getDB()->prepareStatement($sql); $statement->execute(array(FileUtil::addTrailingSlash($templateGroupFolderName))); $row = $statement->fetchArray(); if (!$row['count']) { break; } $templateGroupFolderName = $originalTemplateGroupFolderName . '_' . $i; $i++; } $templateGroupAction = new TemplateGroupAction(array(), 'create', array('data' => array('templateGroupName' => $templateGroupName, 'templateGroupFolderName' => FileUtil::addTrailingSlash($templateGroupFolderName)))); $returnValues = $templateGroupAction->executeAction(); $styleData['templateGroupID'] = $returnValues['returnValues']->templateGroupID; } // import images if (!empty($data['images']) && $data['imagesPath'] != 'images/') { // create images folder if necessary $imagesLocation = self::getFileLocation($data['imagesPath']); $styleData['imagePath'] = FileUtil::getRelativePath(WCF_DIR, $imagesLocation); $index = $tar->getIndexByFilename($data['images']); if ($index !== false) { // extract images tar $destination = FileUtil::getTemporaryFilename('images_'); $tar->extract($index, $destination); // open images tar $imagesTar = new Tar($destination); $contentList = $imagesTar->getContentList(); foreach ($contentList as $key => $val) { if ($val['type'] == 'file') { $imagesTar->extract($key, $imagesLocation . basename($val['filename'])); FileUtil::makeWritable($imagesLocation . basename($val['filename'])); } } // delete tmp file $imagesTar->close(); @unlink($destination); } } // import templates if (!empty($data['templates'])) { $index = $tar->getIndexByFilename($data['templates']); if ($index !== false) { // extract templates tar $destination = FileUtil::getTemporaryFilename('templates_'); $tar->extract($index, $destination); // open templates tar and group templates by package $templatesTar = new Tar($destination); $contentList = $templatesTar->getContentList(); $packageToTemplates = array(); foreach ($contentList as $val) { if ($val['type'] == 'file') { $folders = explode('/', $val['filename']); $packageName = array_shift($folders); if (!isset($packageToTemplates[$packageName])) { $packageToTemplates[$packageName] = array(); } $packageToTemplates[$packageName][] = array('index' => $val['index'], 'filename' => implode('/', $folders)); } } // copy templates foreach ($packageToTemplates as $package => $templates) { // try to find package $sql = "SELECT\t*\n\t\t\t\t\t\tFROM\twcf" . WCF_N . "_package\n\t\t\t\t\t\tWHERE\tpackage = ?\n\t\t\t\t\t\t\tAND isApplication = ?"; $statement = WCF::getDB()->prepareStatement($sql); $statement->execute(array($package, 1)); while ($row = $statement->fetchArray()) { // get template path $templatesDir = FileUtil::addTrailingSlash(FileUtil::getRealPath(WCF_DIR . $row['packageDir']) . 'templates/' . $templateGroupFolderName); // create template path if (!file_exists($templatesDir)) { @mkdir($templatesDir, 0777); FileUtil::makeWritable($templatesDir); } // copy templates foreach ($templates as $template) { $templatesTar->extract($template['index'], $templatesDir . $template['filename']); TemplateEditor::create(array('application' => Package::getAbbreviation($package), 'packageID' => $row['packageID'], 'templateName' => str_replace('.tpl', '', $template['filename']), 'templateGroupID' => $styleData['templateGroupID'])); } } } // delete tmp file $templatesTar->close(); @unlink($destination); } } // save style if ($style !== null) { $style->update($styleData); } else { $styleData['packageID'] = $packageID; $style = new StyleEditor(self::create($styleData)); } // import preview image if (!empty($data['image'])) { $fileExtension = mb_substr($data['image'], mb_strrpos($data['image'], '.')); $index = $tar->getIndexByFilename($data['image']); if ($index !== false) { $filename = WCF_DIR . 'images/stylePreview-' . $style->styleID . $fileExtension; $tar->extract($index, $filename); FileUtil::makeWritable($filename); if (file_exists($filename)) { $style->update(array('image' => 'stylePreview-' . $style->styleID . $fileExtension)); } } } $tar->close(); // handle descriptions if (!empty($data['description'])) { self::saveLocalizedDescriptions($style, $data['description']); LanguageFactory::getInstance()->deleteLanguageCache(); } if ($data['default']) { $style->setAsDefault(); } return $style; }
/** * Returns the database table name for the object type's search index. * * @param mixed $objectType * @param \wcf\data\package\Package $package * @return string */ public static function getTableName($objectType, $package = null) { if (is_string($objectType)) { $objectType = self::getInstance()->getObjectType($objectType); } if ($objectType->searchindex) { $tableName = $objectType->searchindex; if (!empty($tableName)) { if (empty(self::$packages)) { $packageList = new PackageList(); $packageList->getConditionBuilder()->add('package.isApplication = ?', array(1)); $packageList->readObjects(); self::$packages = $packageList->getObjects(); } // replace app1_ with app{WCF_N}_ in the table name foreach (self::$packages as $package) { $abbreviation = Package::getAbbreviation($package->package); $tableName = str_replace($abbreviation . '1_', $abbreviation . WCF_N . '_', $tableName); } return $tableName; } } return 'wcf' . WCF_N . '_search_index_' . substr(sha1($objectType->objectType), 0, 8); }
/** * Loads an application on runtime, do not use this outside the package installation. * * @param integer $packageID */ public static function loadRuntimeApplication($packageID) { $package = new Package($packageID); $application = new Application($packageID); $abbreviation = Package::getAbbreviation($package->package); $packageDir = FileUtil::getRealPath(WCF_DIR . $package->packageDir); self::$autoloadDirectories[$abbreviation] = $packageDir . 'lib/'; self::$applications[$abbreviation] = $application; self::getTPL()->addApplication($abbreviation, $packageDir . 'acp/templates/'); }
/** * @see wcf\system\package\plugin\IPackageInstallationPlugin::install() */ public function install() { parent::install(); // extract sql file from archive if ($queries = $this->getSQL($this->instruction['value'])) { $package = $this->installation->getPackage(); if ($package->parentPackageID) { // package is a plugin; get parent package $package = $package->getParentPackage(); } if ($package->isApplication == 1) { // package is application $packageAbbr = Package::getAbbreviation($package->package); $tablePrefix = WCF_N . '_' . $package->instanceNo . '_'; // Replace the variable xyz1_1 with $tablePrefix in the table names. $queries = StringUtil::replace($packageAbbr . '1_1_', $packageAbbr . $tablePrefix, $queries); } // replace wcf1_ with the actual WCF_N value $queries = str_replace("wcf1_", "wcf" . WCF_N . "_", $queries); // check queries $parser = new PackageInstallationSQLParser($queries, $this->installation->getPackage(), $this->installation->getAction()); $conflicts = $parser->test(); if (!empty($conflicts)) { if (isset($conflicts['CREATE TABLE']) || isset($conflicts['DROP TABLE'])) { if (!PackageInstallationFormManager::findForm($this->installation->queue, 'overwriteDatabaseTables')) { $container = new GroupFormElementContainer(); if (isset($conflicts['CREATE TABLE'])) { $text = implode('<br />', $conflicts['CREATE TABLE']); $label = WCF::getLanguage()->get('wcf.acp.package.error.sql.createTable'); $description = WCF::getLanguage()->get('wcf.acp.package.error.sql.createTable.description'); $element = new LabelFormElement($container); $element->setLabel($label); $element->setText($text); $element->setDescription($description); $container->appendChild($element); } if (isset($conflicts['DROP TABLE'])) { $text = implode('<br />', $conflicts['DROP TABLE']); $label = WCF::getLanguage()->get('wcf.acp.package.error.sql.dropTable'); $description = WCF::getLanguage()->get('wcf.acp.package.error.sql.dropTable.description'); $element = new LabelFormElement($container); $element->setLabel($label); $element->setText($text); $element->setDescription($description); $container->appendChild($element); } $document = new FormDocument('overwriteDatabaseTables'); $document->appendContainer($container); PackageInstallationFormManager::registerForm($this->installation->queue, $document); return $document; } else { /* * At this point the user decided to continue the installation (he would called the rollback * otherwise), thus we do not care about the form anymore */ } } // ask user here // search default value in session if (!WCF::getSession()->getVar('overrideAndDontAskAgain')) { // show page if (!empty($_POST['override']) || !empty($_POST['overrideAndDontAskAgain'])) { if (!empty($_POST['overrideAndDontAskAgain'])) { WCF::getSession()->register('overrideAndDontAskAgain', true); WCF::getSession()->update(); } } else { WCF::getTPL()->assign('conflicts', $conflicts); WCF::getTPL()->display('packageInstallationCheckOverrideTables'); exit; } } } // execute queries $parser->execute(); // log changes $parser->log(); } }
/** * @see \wcf\form\IForm::save() */ public function save() { parent::save(); if (empty($this->application)) { $this->application = Package::getAbbreviation(PackageCache::getInstance()->getPackage($this->packageID)->package); } $this->objectAction = new TemplateAction(array(), 'create', array('data' => array_merge($this->additionalFields, array('application' => $this->application, 'templateName' => $this->tplName, 'packageID' => $this->packageID, 'templateGroupID' => $this->templateGroupID)), 'source' => $this->templateSource)); $this->objectAction->executeAction(); $this->saved(); // reset values $this->tplName = $this->templateSource = ''; $this->templateGroupID = 0; // show success WCF::getTPL()->assign(array('success' => true)); }
/** * Prompts for a text input for package directory (applies for applications only) * * @return \wcf\system\form\FormDocument */ protected function promptPackageDir() { if (!PackageInstallationFormManager::findForm($this->queue, 'packageDir')) { $container = new GroupFormElementContainer(); $packageDir = new TextInputFormElement($container); $packageDir->setName('packageDir'); $packageDir->setLabel(WCF::getLanguage()->get('wcf.acp.package.packageDir.input')); $defaultPath = FileUtil::addTrailingSlash(FileUtil::unifyDirSeparator(dirname(WCF_DIR))); // check if there is already an application $sql = "SELECT\tCOUNT(*) AS count\n\t\t\t\tFROM\twcf" . WCF_N . "_package\n\t\t\t\tWHERE\tpackageDir = ?"; $statement = WCF::getDB()->prepareStatement($sql); $statement->execute(array('../')); $row = $statement->fetchArray(); if ($row['count']) { // use abbreviation $defaultPath .= strtolower(Package::getAbbreviation($this->getPackage()->package)) . '/'; } $packageDir->setValue($defaultPath); $container->appendChild($packageDir); $document = new FormDocument('packageDir'); $document->appendContainer($container); PackageInstallationFormManager::registerForm($this->queue, $document); return $document; } else { $document = PackageInstallationFormManager::getForm($this->queue, 'packageDir'); $document->handleRequest(); $packageDir = FileUtil::addTrailingSlash(FileUtil::getRealPath(FileUtil::unifyDirSeparator($document->getValue('packageDir')))); if ($packageDir === '/') { $packageDir = ''; } if ($packageDir !== null) { // validate package dir if (file_exists($packageDir . 'global.php')) { $document->setError('packageDir', WCF::getLanguage()->get('wcf.acp.package.packageDir.notAvailable')); return $document; } // set package dir $packageEditor = new PackageEditor($this->getPackage()); $packageEditor->update(array('packageDir' => FileUtil::getRelativePath(WCF_DIR, $packageDir))); // determine domain path, in some environments (e.g. ISPConfig) the $_SERVER paths are // faked and differ from the real filesystem path if (PACKAGE_ID) { $wcfDomainPath = ApplicationHandler::getInstance()->getWCF()->domainPath; } else { $sql = "SELECT\tdomainPath\n\t\t\t\t\t\tFROM\twcf" . WCF_N . "_application\n\t\t\t\t\t\tWHERE\tpackageID = ?"; $statement = WCF::getDB()->prepareStatement($sql); $statement->execute(array(1)); $row = $statement->fetchArray(); $wcfDomainPath = $row['domainPath']; } $documentRoot = str_replace($wcfDomainPath, '', FileUtil::unifyDirSeparator(WCF_DIR)); $domainPath = str_replace($documentRoot, '', $packageDir); // update application path $application = new Application($this->getPackage()->packageID); $applicationEditor = new ApplicationEditor($application); $applicationEditor->update(array('domainPath' => $domainPath, 'cookiePath' => $domainPath)); // create directory and set permissions @mkdir($packageDir, 0777, true); FileUtil::makeWritable($packageDir); } return null; } }
/** * Returns true if the package is an application and has an unique abbrevation. * * @return boolean */ public function hasUniqueAbbreviation() { if (!$this->packageInfo['isApplication']) { return true; } $sql = "SELECT\tCOUNT(*)\n\t\t\tFROM\twcf" . WCF_N . "_package\n\t\t\tWHERE\tisApplication = ?\n\t\t\t\tAND package LIKE ?"; $statement = WCF::getDB()->prepareStatement($sql); $statement->execute(array(1, '%.' . Package::getAbbreviation($this->packageInfo['name']))); return $statement->fetchColumn(); }
/** * @see \wcf\system\package\plugin\AbstractOptionPackageInstallationPlugin::saveOption() */ protected function saveOption($option, $categoryName, $existingOptionID = 0) { // default values $optionName = $optionType = $defaultValue = $validationPattern = $selectOptions = $enableOptions = $permissions = $options = ''; $showOrder = null; $hidden = $supportI18n = $requireI18n = 0; // get values if (isset($option['name'])) { $optionName = $option['name']; } if (isset($option['optiontype'])) { $optionType = $option['optiontype']; } if (isset($option['defaultvalue'])) { $defaultValue = WCF::getLanguage()->get($option['defaultvalue']); } if (isset($option['validationpattern'])) { $validationPattern = $option['validationpattern']; } if (isset($option['enableoptions'])) { $enableOptions = $option['enableoptions']; } if (isset($option['showorder'])) { $showOrder = intval($option['showorder']); } if (isset($option['hidden'])) { $hidden = intval($option['hidden']); } $showOrder = $this->getShowOrder($showOrder, $categoryName, 'categoryName'); if (isset($option['selectoptions'])) { $selectOptions = $option['selectoptions']; } if (isset($option['permissions'])) { $permissions = $option['permissions']; } if (isset($option['options'])) { $options = $option['options']; } if (isset($option['supporti18n'])) { $supportI18n = $option['supporti18n']; } if (isset($option['requirei18n'])) { $requireI18n = $option['requirei18n']; } // collect additional tags and their values $additionalData = array(); foreach ($option as $tag => $value) { if (!in_array($tag, self::$reservedTags)) { $additionalData[$tag] = $value; } } // build update or create data $data = array('categoryName' => $categoryName, 'optionType' => $optionType, 'validationPattern' => $validationPattern, 'selectOptions' => $selectOptions, 'showOrder' => $showOrder, 'enableOptions' => $enableOptions, 'hidden' => $hidden, 'permissions' => $permissions, 'options' => $options, 'supportI18n' => $supportI18n, 'requireI18n' => $requireI18n, 'additionalData' => serialize($additionalData)); // try to find an existing option for updating $sql = "SELECT\t*\n\t\t\tFROM\twcf" . WCF_N . "_" . $this->tableName . "\n\t\t\tWHERE\toptionName = ?"; $statement = WCF::getDB()->prepareStatement($sql); $statement->execute(array($optionName)); $row = $statement->fetchArray(); // result was 'false' thus create a new item if (!$row) { // set the value of 'app_install_date' to the current timestamp if ($hidden && $optionType == 'integer' && $this->installation->getPackage()->isApplication) { $abbreviation = Package::getAbbreviation($this->installation->getPackage()->package); if ($optionName == $abbreviation . '_install_date') { $defaultValue = TIME_NOW; } } $data['optionName'] = $optionName; $data['packageID'] = $this->installation->getPackageID(); $data['optionValue'] = $defaultValue; OptionEditor::create($data); } else { // editing an option from a different package if ($row['packageID'] != $this->installation->getPackageID()) { throw new SystemException("Option '" . $optionName . "' already exists, but is owned by a different package"); } // update existing item $optionObj = new Option(null, $row); $optionEditor = new OptionEditor($optionObj); $optionEditor->update($data); } }