public static function analyzeAddon($Path, $ThrowError = true)
{
if (!file_exists($Path)) {
if ($ThrowError) {
throw new Exception("{$Path} not found.", 404);
}
return false;
}
$Addon = [];
$Result = [];
$InfoPaths = array('/settings/about.php', '/default.php', '/class.*.plugin.php', '/about.php', '/definitions.php', '/index.php', 'vanilla2export.php');
// Get the list of potential files to analyze.
if (is_dir($Path)) {
$Entries = self::getInfoFiles($Path, $InfoPaths);
$DeleteEntries = false;
} else {
$Entries = self::getInfoZip($Path, $InfoPaths, false, $ThrowError);
$DeleteEntries = true;
}
foreach ($Entries as $Entry) {
if ($Entry['Name'] == '/index.php') {
// This could be the core vanilla package.
$Version = self::parseCoreVersion($Entry['Path']);
if (!$Version) {
continue;
}
// The application was confirmed.
$Addon = array('AddonKey' => 'vanilla', 'AddonTypeID' => ADDON_TYPE_CORE, 'Name' => 'Vanilla', 'Description' => 'Vanilla is an open-source, standards-compliant, multi-lingual, fully extensible discussion forum for the web. Anyone who has web-space that meets the requirements can download and use Vanilla for free!', 'Version' => $Version, 'License' => 'GPLv2', 'Path' => $Entry['Path']);
break;
} elseif ($Entry['Name'] == 'vanilla2export.php') {
// This could be the vanilla porter.
$Version = self::parseCoreVersion($Entry['Path']);
if (!$Version) {
continue;
}
$Addon = array('AddonKey' => 'porter', 'AddonTypeID' => ADDON_TYPE_CORE, 'Name' => 'Vanilla Porter', 'Description' => 'Drop this script in your existing site and navigate to it in your web browser to export your existing forum data to the Vanilla 2 import format.', 'Version' => $Version, 'License' => 'GPLv2', 'Path' => $Entry['Path']);
break;
} else {
// This could be an addon.
$Info = self::parseInfoArray($Entry['Path']);
if (!is_array($Info) && count($Info)) {
continue;
}
$Key = key($Info);
$Variable = $Info['Variable'];
$Info = $Info[$Key];
// Validate the addon.
$Name = $Entry['Name'];
$Valid = true;
if (!val('Name', $Info)) {
$Info['Name'] = $Key;
}
// Validate basic fields.
$checkResult = self::checkRequiredFields($Info);
if (count($checkResult)) {
$Result = array_merge($Result, $checkResult);
$Valid = false;
}
// Validate folder name matches key.
if (isset($Entry['Base']) && strcasecmp($Entry['Base'], $Key) != 0 && $Variable != 'ThemeInfo') {
$Result[] = "{$Name}: The addon's key is not the same as its folder name.";
$Valid = false;
}
if (!$Valid) {
continue;
}
// The addon is valid.
$Addon = array_merge(array('AddonKey' => $Key, 'AddonTypeID' => ''), $Info);
switch ($Variable) {
case 'ApplicationInfo':
$Addon['AddonTypeID'] = ADDON_TYPE_APPLICATION;
break;
case 'LocaleInfo':
$Addon['AddonTypeID'] = ADDON_TYPE_LOCALE;
break;
case 'PluginInfo':
$Addon['AddonTypeID'] = ADDON_TYPE_PLUGIN;
break;
case 'ThemeInfo':
$Addon['AddonTypeID'] = ADDON_TYPE_THEME;
break;
}
}
}
if ($DeleteEntries) {
$FolderPath = substr($Path, 0, -4);
Gdn_FileSystem::removeFolder($FolderPath);
}
// Add the addon requirements.
if (!empty($Addon)) {
$Requirements = arrayTranslate($Addon, ['RequiredApplications' => 'Applications', 'RequiredPlugins' => 'Plugins', 'RequiredThemes' => 'Themes']);
foreach ($Requirements as $Type => $Items) {
if (!is_array($Items)) {
unset($Requirements[$Type]);
}
}
$Addon['Requirements'] = dbencode($Requirements);
$Addon['Checked'] = true;
$Addon['Path'] = $Path;
$UploadsPath = PATH_UPLOADS . '/';
if (stringBeginsWith($Addon['Path'], $UploadsPath)) {
$Addon['File'] = substr($Addon['Path'], strlen($UploadsPath));
}
if (is_file($Path)) {
$Addon['MD5'] = md5_file($Path);
$Addon['FileSize'] = filesize($Path);
}
} elseif ($ThrowError) {
$Msg = implode("\n", $Result);
throw new Gdn_UserException($Msg, 400);
} else {
return false;
}
return $Addon;
}