From 377c9a90c65fea4979b2711e78e4904454d315fe Mon Sep 17 00:00:00 2001 From: homelab-runtime-publisher Date: Wed, 9 Sep 2026 12:52:34 +0000 Subject: [PATCH] runtime: publish SUPPORT-260909-GRAM-XF-PROCESSING-NARROW-066 --- ...-260909-GRAM-XF-PROCESSING-NARROW-066.json | 38 ++++++++++++++++ ...T-260909-GRAM-XF-PROCESSING-NARROW-066.txt | 44 +++++++++++++++++++ runtime/latest.json | 16 +++---- runtime/latest.txt | 26 +++++------ 4 files changed, 103 insertions(+), 21 deletions(-) create mode 100644 runtime/history/SUPPORT-260909-GRAM-XF-PROCESSING-NARROW-066.json create mode 100644 runtime/history/SUPPORT-260909-GRAM-XF-PROCESSING-NARROW-066.txt diff --git a/runtime/history/SUPPORT-260909-GRAM-XF-PROCESSING-NARROW-066.json b/runtime/history/SUPPORT-260909-GRAM-XF-PROCESSING-NARROW-066.json new file mode 100644 index 00000000..bb970264 --- /dev/null +++ b/runtime/history/SUPPORT-260909-GRAM-XF-PROCESSING-NARROW-066.json @@ -0,0 +1,38 @@ +{ + "schema_version": 1, + "channel": "homelab-runtime", + "command_id": "SUPPORT-260909-GRAM-XF-PROCESSING-NARROW-066", + "status": "OK", + "rc": 0, + "host": "pve01", + "mode": "read-only", + "component": "gram-support-processing-narrow", + "started_at_utc": "2026-09-09T12:52:31Z", + "finished_at_utc": "2026-09-09T12:52:33Z", + "reference_register_checked": true, + "reference_sha256": "5a3d8e5154c41cb582a4e0aca68090be1f0138918bf82131a948df326f9d8d66", + "error_register_checked": true, + "error_register_sha256": "3b09a553ec0f527ed3afeed4753f52a74ee3036045bbfb3c685e9f8af4ba7ba0", + "command_sha256": "b3716049942ceaea06095b5ef78a11b817e642afcc6903f53a48e9f209af6efa", + "duplicate_failed_command_blocked": false, + "block_reason": null, + "execution_started": true, + "change_declared": false, + "result_contract_valid": true, + "result_contract_status": null, + "result_contract_error": null, + "command_rc": 0, + "changes_made": false, + "rollback_started": false, + "rollback_restored": null, + "mutation_outcome": "NO_MUTATION", + "sanitized": true, + "secrets_included": false, + "private_addresses_included": false, + "raw_evidence_retained_locally": true, + "raw_evidence_sha256": "f3bacd113632355b0404ed76453af3e803d539bb8c332baf6b14b126f66f47ee", + "sanitized_output_sha256": "f3bacd113632355b0404ed76453af3e803d539bb8c332baf6b14b126f66f47ee", + "output_truncated_in_json": false, + "full_sanitized_output_url": "https://git.gram1.ru/.well-known/homelab-runtime/latest.txt", + "output": "SUPPORT066_BEGIN\nERROR_REGISTER_CHECK=OK\nREFERENCE_CHECK=OK\nAUTHORITY_CHECK_SCOPE=READABILITY_ONLY_INCIDENTS_NOT_CLOSED\nRUNNER_SHA256=b248a4c32c9cc64e5747e7dce6c7fc0a23f5124a77c71ce72e27a81aceae9d2d\nSUPPORT066_QGA_STATE={\"exitcode\":0,\"state\":\"COMPLETE\"}\nSUPPORT066_VM211={\"command_id\":\"SUPPORT-260909-GRAM-XF-PROCESSING-NARROW-066\",\"decision\":\"NARROW_PROCESSING_STATE_CAPTURED\",\"guest\":\"newfi-staging\",\"holds\":[],\"identity_ok\":true,\"probe\":{\"rc\":0,\"stderr_sha256\":\"\"},\"probe_after\":{\"rc\":0,\"stderr_sha256\":\"\"},\"scope\":\"READ_ONLY_NO_MUTATION\",\"source_evidence\":[{\"file\":\"src/XF/Cli/Command/AddOn/AbstractSetupStep.php\",\"matches\":[{\"line\":42,\"text\":\"\\t{\"},{\"line\":43,\"text\":\"\\t\\t$id = $input->getArgument('id');\"},{\"line\":44,\"text\":\"\"},{\"line\":45,\"text\":\"\\t\\t$addOn = $this->checkEditableAddOn($id, $error);\"},{\"line\":46,\"text\":\"\\t\\tif (!$addOn)\"},{\"line\":47,\"text\":\"\\t\\t{\"},{\"line\":48,\"text\":\"\\t\\t\\t$output->writeln('' . $error . '');\"},{\"line\":49,\"text\":\"\\t\\t\\treturn 1;\"},{\"line\":50,\"text\":\"\\t\\t}\"},{\"line\":51,\"text\":\"\"},{\"line\":52,\"text\":\"\\t\\t$setup = $addOn->getSetup();\"},{\"line\":53,\"text\":\"\"},{\"line\":54,\"text\":\"\\t\\tif (!$setup)\"},{\"line\":55,\"text\":\"\\t\\t{\"},{\"line\":56,\"text\":\"\\t\\t\\t$output->writeln(\\\"Setup class for add-on could not be found.\\\");\"},{\"line\":57,\"text\":\"\\t\\t\\treturn 1;\"},{\"line\":58,\"text\":\"\\t\\t}\"},{\"line\":59,\"text\":\"\"},{\"line\":60,\"text\":\"\\t\\t$step = $input->getArgument('step');\"},{\"line\":61,\"text\":\"\\t\\t$version = null;\"},{\"line\":62,\"text\":\"\\t\\t$params = [];\"},{\"line\":63,\"text\":\"\"},{\"line\":64,\"text\":\"\\t\\t$stepType = $this->getStepType();\"},{\"line\":65,\"text\":\"\\t\\tif ($stepType == 'upgrade')\"},{\"line\":66,\"text\":\"\\t\\t{\"},{\"line\":67,\"text\":\"\\t\\t\\t$version = $input->getArgument('version');\"},{\"line\":68,\"text\":\"\\t\\t}\"},{\"line\":69,\"text\":\"\"},{\"line\":70,\"text\":\"\\t\\t$setup->prepareForAction($stepType);\"},{\"line\":71,\"text\":\"\"},{\"line\":72,\"text\":\"\\t\\tdo\"},{\"line\":73,\"text\":\"\\t\\t{\"},{\"line\":74,\"text\":\"\\t\\t\\t$result = $this->runStep($setup, $output, $stepType, $step, $version, $params);\"},{\"line\":75,\"text\":\"\\t\\t\\tif (!($result instanceof StepResult))\"},{\"line\":76,\"text\":\"\\t\\t\\t{\"},{\"line\":77,\"text\":\"\\t\\t\\t\\t$this->clearStatus($output, \\\"Must return a StepResult object.\\\");\"},{\"line\":78,\"text\":\"\\t\\t\\t\\treturn 1;\"},{\"line\":79,\"text\":\"\\t\\t\\t}\"},{\"line\":80,\"text\":\"\\t\\t\\telse\"},{\"line\":81,\"text\":\"\\t\\t\\t{\"},{\"line\":82,\"text\":\"\\t\\t\\t\\tif ($result->complete)\"},{\"line\":83,\"text\":\"\\t\\t\\t\\t{\"},{\"line\":84,\"text\":\"\\t\\t\\t\\t\\t$loop = false;\"},{\"line\":85,\"text\":\"\\t\\t\\t\\t}\"},{\"line\":86,\"text\":\"\\t\\t\\t\\telse if (is_int($result))\"},{\"line\":87,\"text\":\"\\t\\t\\t\\t{\"},{\"line\":88,\"text\":\"\\t\\t\\t\\t\\t$loop = false;\"},{\"line\":89,\"text\":\"\\t\\t\\t\\t}\"},{\"line\":90,\"text\":\"\\t\\t\\t\\telse\"},{\"line\":91,\"text\":\"\\t\\t\\t\\t{\"},{\"line\":92,\"text\":\"\\t\\t\\t\\t\\t$params = $result->params;\"},{\"line\":93,\"text\":\"\\t\\t\\t\\t\\t$loop = true;\"},{\"line\":104,\"text\":\"\\tprotected function runStep(AbstractSetup $setup, OutputInterface $output, $stepType, $step, $version = null, array $params = [])\"},{\"line\":105,\"text\":\"\\t{\"},{\"line\":106,\"text\":\"\\t\\t$method = $stepType;\"},{\"line\":107,\"text\":\"\"},{\"line\":108,\"text\":\"\\t\\tswitch ($method)\"},{\"line\":109,\"text\":\"\\t\\t{\"},{\"line\":110,\"text\":\"\\t\\t\\tcase 'install':\"},{\"line\":111,\"text\":\"\\t\\t\\tcase 'uninstall':\"},{\"line\":112,\"text\":\"\\t\\t\\t\\tif ($step)\"},{\"line\":113,\"text\":\"\\t\\t\\t\\t{\"},{\"line\":114,\"text\":\"\\t\\t\\t\\t\\t$method .= 'Step' . $step;\"},{\"line\":115,\"text\":\"\\t\\t\\t\\t}\"},{\"line\":116,\"text\":\"\\t\\t\\t\\tbreak;\"},{\"line\":117,\"text\":\"\"},{\"line\":118,\"text\":\"\\t\\t\\tcase 'upgrade':\"},{\"line\":119,\"text\":\"\\t\\t\\t\\tif ($version && $step)\"},{\"line\":120,\"text\":\"\\t\\t\\t\\t{\"},{\"line\":121,\"text\":\"\\t\\t\\t\\t\\t$method .= $version . 'Step' . $step;\"},{\"line\":122,\"text\":\"\\t\\t\\t\\t}\"},{\"line\":123,\"text\":\"\\t\\t\\t\\tbreak;\"},{\"line\":124,\"text\":\"\\t\\t}\"},{\"line\":125,\"text\":\"\"},{\"line\":126,\"text\":\"\\t\\tif (!method_exists($setup, $method))\"}],\"sha256\":\"86ac6e9eda2202a75f3566a6bf20b14b5cc5171a823e0a23de0e66d0e8c0a8b7\"},{\"file\":\"src/XF/Cli/Command/AddOn/Create.php\",\"matches\":[{\"line\":40,\"text\":\"\\t\\tif ($devOutput->isAddOnSkipped($addOnId))\"},{\"line\":41,\"text\":\"\\t\\t{\"},{\"line\":42,\"text\":\"\\t\\t\\t$output->writeln(\\\"Development output for this add-on ID has been disabled. Cannot continue.\\\");\"},{\"line\":43,\"text\":\"\\t\\t\\tif (strtolower(substr($addOnId, 0, 2)) == 'xf')\"},{\"line\":44,\"text\":\"\\t\\t\\t{\"},{\"line\":45,\"text\":\"\\t\\t\\t\\t$output->writeln(\\\"Note: use of add-on IDs starting with 'xf' is strongly discouraged.\\\");\"},{\"line\":46,\"text\":\"\\t\\t\\t}\"},{\"line\":47,\"text\":\"\\t\\t\\treturn 1;\"},{\"line\":48,\"text\":\"\\t\\t}\"},{\"line\":49,\"text\":\"\"},{\"line\":50,\"text\":\"\\t\\t$checkPath = \\\\XF::getAddOnDirectory();\"},{\"line\":51,\"text\":\"\"},{\"line\":52,\"text\":\"\\t\\t$addOnManager = \\\\XF::app()->addOnManager();\"},{\"line\":53,\"text\":\"\\t\\tforeach ($addOnManager->getAllAddOns() AS $existingAddOnId => $existingAddOn)\"},{\"line\":54,\"text\":\"\\t\\t{\"},{\"line\":55,\"text\":\"\\t\\t\\tif ($existingAddOnId !== $addOnId && strcasecmp($existingAddOnId, $addOnId) === 0)\"},{\"line\":56,\"text\":\"\\t\\t\\t{\"},{\"line\":57,\"text\":\"\\t\\t\\t\\t$output->writeln(\\\"Add-on ID '{$addOnId}' conflicts with existing add-on '{$existingAddOnId}' (case mismatch).\\\");\"},{\"line\":58,\"text\":\"\\t\\t\\t\\treturn 1;\"},{\"line\":59,\"text\":\"\\t\\t\\t}\"},{\"line\":60,\"text\":\"\\t\\t}\"},{\"line\":61,\"text\":\"\"},{\"line\":62,\"text\":\"\\t\\tif (strpos($addOnId, '/') !== false)\"},{\"line\":63,\"text\":\"\\t\\t{\"},{\"line\":64,\"text\":\"\\t\\t\\t$addOnIdParts = explode('/', $addOnId);\"},{\"line\":65,\"text\":\"\\t\\t\\t$vendor = reset($addOnIdParts);\"},{\"line\":66,\"text\":\"\"},{\"line\":67,\"text\":\"\\t\\t\\tif (file_exists(\\\\XF::getAddOnDirectory() . \\\\XF::$DS . $vendor))\"},{\"line\":68,\"text\":\"\\t\\t\\t{\"},{\"line\":69,\"text\":\"\\t\\t\\t\\t$checkPath = \\\\XF::getAddOnDirectory() . \\\\XF::$DS . $vendor;\"},{\"line\":70,\"text\":\"\\t\\t\\t}\"},{\"line\":71,\"text\":\"\"},{\"line\":72,\"text\":\"\\t\\t\\tif ($addOnDir = opendir(\\\\XF::getAddOnDirectory()))\"},{\"line\":73,\"text\":\"\\t\\t\\t{\"},{\"line\":74,\"text\":\"\\t\\t\\t\\twhile (($dir = readdir($addOnDir)) !== false)\"},{\"line\":75,\"text\":\"\\t\\t\\t\\t{\"},{\"line\":76,\"text\":\"\\t\\t\\t\\t\\tif (strcasecmp($dir, $vendor) == 0 && $dir != $vendor)\"},{\"line\":77,\"text\":\"\\t\\t\\t\\t\\t{\"},{\"line\":78,\"text\":\"\\t\\t\\t\\t\\t\\t$output->writeln(\\\"The '{$checkPath}' directory conflicts with an existing directory with the same name but a different case.\\\");\"},{\"line\":79,\"text\":\"\\t\\t\\t\\t\\t\\treturn 1;\"},{\"line\":80,\"text\":\"\\t\\t\\t\\t\\t}\"},{\"line\":81,\"text\":\"\\t\\t\\t\\t}\"},{\"line\":82,\"text\":\"\\t\\t\\t\\tclosedir($addOnDir);\"},{\"line\":83,\"text\":\"\\t\\t\\t}\"},{\"line\":84,\"text\":\"\\t\\t}\"},{\"line\":85,\"text\":\"\"},{\"line\":86,\"text\":\"\\t\\tif (!is_writable($checkPath))\"},{\"line\":87,\"text\":\"\\t\\t{\"},{\"line\":88,\"text\":\"\\t\\t\\t$checkPathPrintable = str_replace(\\\\XF::getRootDirectory() . \\\\XF::$DS, '', $checkPath);\"},{\"line\":89,\"text\":\"\\t\\t\\t$output->writeln(\\\"The '{$checkPathPrintable}' directory is not writable.\\\");\"},{\"line\":90,\"text\":\"\\t\\t\\treturn 1;\"},{\"line\":91,\"text\":\"\\t\\t}\"},{\"line\":92,\"text\":\"\"},{\"line\":93,\"text\":\"\\t\\t$addOnObj = new AddOn($addOnId, \\\\XF::app()->addOnManager());\"},{\"line\":94,\"text\":\"\"},{\"line\":95,\"text\":\"\\t\\t$jsonPath = $addOnObj->getJsonPath();\"},{\"line\":96,\"text\":\"\"},{\"line\":97,\"text\":\"\\t\\tif (file_exists($jsonPath))\"},{\"line\":98,\"text\":\"\\t\\t{\"},{\"line\":99,\"text\":\"\\t\\t\\t$output->writeln(\\\"The addon.json file already exists at {$jsonPath}. You can create the add-on by installing it from the Admin CP.\\\");\"},{\"line\":100,\"text\":\"\\t\\t\\treturn 1;\"},{\"line\":101,\"text\":\"\\t\\t}\"},{\"line\":102,\"text\":\"\"},{\"line\":103,\"text\":\"\\t\\t$question = new Question(\\\"Enter a title: \\\");\"},{\"line\":104,\"text\":\"\\t\\t$question->setValidator($this->getAddOnQuestionFieldValidator('title'));\"},{\"line\":105,\"text\":\"\\t\\t$title = $helper->ask($input, $output, $question);\"},{\"line\":106,\"text\":\"\\t\\t$output->writeln(\\\"\\\");\"},{\"line\":107,\"text\":\"\"},{\"line\":108,\"text\":\"\\t\\t$question = new Question(\\\"Enter a version ID. This integer will be used for internal version comparisons. Each release of your add-on should increase this number: \\\");\"},{\"line\":109,\"text\":\"\\t\\t$question->setValidator(function ($value)\"},{\"line\":110,\"text\":\"\\t\\t{\"},{\"line\":111,\"text\":\"\\t\\t\\tif (!preg_match('/^[0-9]+$/', $value))\"},{\"line\":112,\"text\":\"\\t\\t\\t{\"},{\"line\":113,\"text\":\"\\t\\t\\t\\tthrow new \\\\InvalidArgumentException(\\\"The version ID should contain numeric values only.\\\");\"},{\"line\":114,\"text\":\"\\t\\t\\t}\"},{\"line\":115,\"text\":\"\\t\\t\\treturn $value;\"},{\"line\":170,\"text\":\"\"},{\"line\":171,\"text\":\"\\t\\t$output->writeln(\\\"\\\");\"},{\"line\":172,\"text\":\"\"},{\"line\":173,\"text\":\"\\t\\t$addOn->preSave();\"},{\"line\":174,\"text\":\"\\t\\tif ($errors = $addOn->getErrors())\"},{\"line\":175,\"text\":\"\\t\\t{\"},{\"line\":176,\"text\":\"\\t\\t\\t$output->writeln(\\\"An unexpected error occurred while saving the add-on: \\\" . reset($errors) . \\\"\\\");\"},{\"line\":177,\"text\":\"\\t\\t\\treturn 1;\"},{\"line\":178,\"text\":\"\\t\\t}\"},{\"line\":179,\"text\":\"\"},{\"line\":180,\"text\":\"\\t\\t$addOn->save();\"},{\"line\":181,\"text\":\"\"},{\"line\":182,\"text\":\"\\t\\tFile::createDirectory($addOnObj->getAddOnDirectory(), false);\"},{\"line\":183,\"text\":\"\"},{\"line\":184,\"text\":\"\\t\\t$json = [\"},{\"line\":185,\"text\":\"\\t\\t\\t'title' => $addOn->title,\"},{\"line\":186,\"text\":\"\\t\\t\\t'version_string' => $addOn->version_string,\"},{\"line\":187,\"text\":\"\\t\\t\\t'version_id' => intval($addOn->version_id),\"},{\"line\":188,\"text\":\"\\t\\t];\"},{\"line\":189,\"text\":\"\\t\\tif ($legacyAddOnId)\"},{\"line\":190,\"text\":\"\\t\\t{\"},{\"line\":191,\"text\":\"\\t\\t\\t$json['legacy_addon_id'] = $legacyAddOnId;\"},{\"line\":192,\"text\":\"\\t\\t}\"},{\"line\":220,\"text\":\"\\t\\t\\t\\t$setupContent = <<< SETUP\"}],\"sha256\":\"4ff8f77caa12327158b9a6ba6ed2ffe85b959011279be5a70a8b3e77f75204f5\"},{\"file\":\"src/XF/Cli/Command/AddOn/UninstallStep.php\",\"matches\":[{\"line\":1,\"text\":\"addArgument(\"},{\"line\":17,\"text\":\"\\t\\t\\t'step',\"},{\"line\":18,\"text\":\"\\t\\t\\tInputArgument::REQUIRED,\"},{\"line\":19,\"text\":\"\\t\\t\\t'The step number to run.'\"},{\"line\":20,\"text\":\"\\t\\t);\"},{\"line\":21,\"text\":\"\\t}\"},{\"line\":22,\"text\":\"}\"}],\"sha256\":\"d69b287acd3ea5c02bf23492e1bdef465fb75f22f00b45acdb4ffafe547260e5\"},{\"file\":\"src/XF/AddOn/AbstractSetup.php\",\"matches\":[{\"line\":32,\"text\":\"\\tabstract public function upgrade(array $stepParams = []);\"},{\"line\":33,\"text\":\"\"},{\"line\":34,\"text\":\"\\t/**\"},{\"line\":35,\"text\":\"\\t * @param array $stepParams\"},{\"line\":36,\"text\":\"\\t *\"},{\"line\":37,\"text\":\"\\t * @return null|StepResult\"},{\"line\":38,\"text\":\"\\t */\"},{\"line\":39,\"text\":\"\\tabstract public function uninstall(array $stepParams = []);\"},{\"line\":40,\"text\":\"\"},{\"line\":41,\"text\":\"\\tpublic function __construct(AddOn $addOn, App $app)\"},{\"line\":42,\"text\":\"\\t{\"},{\"line\":43,\"text\":\"\\t\\t$this->addOn = $addOn;\"},{\"line\":44,\"text\":\"\\t\\t$this->app = $app;\"},{\"line\":45,\"text\":\"\\t}\"},{\"line\":46,\"text\":\"\"},{\"line\":47,\"text\":\"\\t/**\"},{\"line\":48,\"text\":\"\\t * Perform additional requirement checks.\"},{\"line\":49,\"text\":\"\\t *\"},{\"line\":50,\"text\":\"\\t * @param list $errors Errors will block the setup from continuing\"},{\"line\":51,\"text\":\"\\t * @param list $warnings Warnings will be displayed but allow the user to continue setup\"},{\"line\":52,\"text\":\"\\t *\"},{\"line\":53,\"text\":\"\\t * @return void\"},{\"line\":54,\"text\":\"\\t */\"},{\"line\":86,\"text\":\"\\t\\t$this->app->jobManager()->enqueueUnique($uniqueId, FileCleanUp::class, [\"},{\"line\":87,\"text\":\"\\t\\t\\t'addon_id' => $addOn->addon_id,\"},{\"line\":88,\"text\":\"\\t\\t], false);\"},{\"line\":89,\"text\":\"\\t}\"},{\"line\":90,\"text\":\"\"},{\"line\":91,\"text\":\"\\tpublic function prepareForAction($action)\"},{\"line\":92,\"text\":\"\\t{\"},{\"line\":93,\"text\":\"\\t\\tif ($action == 'uninstall')\"},{\"line\":94,\"text\":\"\\t\\t{\"},{\"line\":95,\"text\":\"\\t\\t\\t\\\\XF::db()->ignoreLegacyTableWriteError(true);\"},{\"line\":96,\"text\":\"\\t\\t}\"},{\"line\":97,\"text\":\"\\t}\"},{\"line\":98,\"text\":\"\"},{\"line\":99,\"text\":\"\\t/**\"},{\"line\":100,\"text\":\"\\t * @param $sql\"},{\"line\":101,\"text\":\"\\t * @param array $bind\"},{\"line\":102,\"text\":\"\\t * @param bool $suppressAll\"},{\"line\":103,\"text\":\"\\t *\"},{\"line\":104,\"text\":\"\\t * @return bool|AbstractStatement\"},{\"line\":105,\"text\":\"\\t * @throws Exception\"},{\"line\":106,\"text\":\"\\t */\"},{\"line\":107,\"text\":\"\\tprotected function query($sql, $bind = [], $suppressAll = false)\"},{\"line\":108,\"text\":\"\\t{\"}],\"sha256\":\"6bdd3fe834e15b963a52c9357f54262f2d12f3c7c3686fc31333b549cddf2d88\"},{\"file\":\"src/XF/AddOn/AddOn.php\",\"matches\":[{\"line\":332,\"text\":\"\\t\\t\\t\\t}\"},{\"line\":333,\"text\":\"\\t\\t\\t}\"},{\"line\":334,\"text\":\"\\t\\t}\"},{\"line\":335,\"text\":\"\"},{\"line\":336,\"text\":\"\\t\\treturn $this->setup;\"},{\"line\":337,\"text\":\"\\t}\"},{\"line\":338,\"text\":\"\"},{\"line\":339,\"text\":\"\\tpublic function isInstalled()\"},{\"line\":340,\"text\":\"\\t{\"},{\"line\":341,\"text\":\"\\t\\tif ($this->installedAddOn === null)\"},{\"line\":342,\"text\":\"\\t\\t{\"},{\"line\":343,\"text\":\"\\t\\t\\treturn false;\"},{\"line\":344,\"text\":\"\\t\\t}\"},{\"line\":345,\"text\":\"\"},{\"line\":346,\"text\":\"\\t\\t$lastAction = $this->installedAddOn->getLastActionStep('install');\"},{\"line\":347,\"text\":\"\\t\\tif ($lastAction !== null)\"},{\"line\":348,\"text\":\"\\t\\t{\"},{\"line\":349,\"text\":\"\\t\\t\\t// we haven't completed the install steps yet, don't consider as installed\"},{\"line\":350,\"text\":\"\\t\\t\\treturn false;\"},{\"line\":351,\"text\":\"\\t\\t}\"},{\"line\":352,\"text\":\"\"},{\"line\":353,\"text\":\"\\t\\treturn true;\"},{\"line\":354,\"text\":\"\\t}\"},{\"line\":355,\"text\":\"\"},{\"line\":356,\"text\":\"\\tpublic function isActive()\"},{\"line\":357,\"text\":\"\\t{\"},{\"line\":358,\"text\":\"\\t\\treturn $this->isInstalled()\"},{\"line\":359,\"text\":\"\\t\\t\\t&& $this->installedAddOn->active;\"},{\"line\":360,\"text\":\"\\t}\"},{\"line\":361,\"text\":\"\"},{\"line\":362,\"text\":\"\\tpublic function isLegacy()\"},{\"line\":363,\"text\":\"\\t{\"},{\"line\":364,\"text\":\"\\t\\treturn $this->isInstalled()\"},{\"line\":365,\"text\":\"\\t\\t\\t&& $this->installedAddOn->is_legacy;\"},{\"line\":366,\"text\":\"\\t}\"},{\"line\":367,\"text\":\"\"},{\"line\":368,\"text\":\"\\tpublic function isDevOutputAvailable()\"},{\"line\":369,\"text\":\"\\t{\"},{\"line\":370,\"text\":\"\\t\\treturn \\\\XF::app()->developmentOutput()->isAddOnOutputAvailable($this->getAddOnId());\"},{\"line\":371,\"text\":\"\\t}\"},{\"line\":372,\"text\":\"\"},{\"line\":373,\"text\":\"\\tpublic function hasMissingFiles()\"},{\"line\":374,\"text\":\"\\t{\"},{\"line\":375,\"text\":\"\\t\\treturn count($this->missingFiles) > 0;\"},{\"line\":376,\"text\":\"\\t}\"},{\"line\":377,\"text\":\"\"},{\"line\":378,\"text\":\"\\tpublic function hasPendingChanges()\"},{\"line\":379,\"text\":\"\\t{\"},{\"line\":380,\"text\":\"\\t\\treturn $this->isInstalled()\"},{\"line\":381,\"text\":\"\\t\\t\\t&& !$this->isLegacy()\"},{\"line\":382,\"text\":\"\\t\\t\\t&& (\"},{\"line\":383,\"text\":\"\\t\\t\\t\\t!$this->isFileVersionValid()\"},{\"line\":384,\"text\":\"\\t\\t\\t\\t|| $this->isJsonHashChanged()\"},{\"line\":385,\"text\":\"\\t\\t\\t);\"},{\"line\":386,\"text\":\"\\t}\"},{\"line\":387,\"text\":\"\"},{\"line\":388,\"text\":\"\\tpublic function hasFaIcon()\"},{\"line\":389,\"text\":\"\\t{\"},{\"line\":390,\"text\":\"\\t\\treturn (\"},{\"line\":391,\"text\":\"\\t\\t\\t$this->icon\"},{\"line\":392,\"text\":\"\\t\\t\\t&& !$this->hasIcon()\"},{\"line\":393,\"text\":\"\\t\\t\\t&& preg_match('#^(fa-|fa[a-z] )#', $this->icon)\"},{\"line\":394,\"text\":\"\\t\\t);\"},{\"line\":395,\"text\":\"\\t}\"},{\"line\":431,\"text\":\"\\tpublic function isAvailable()\"},{\"line\":432,\"text\":\"\\t{\"},{\"line\":433,\"text\":\"\\t\\treturn count($this->missingFiles) == 0;\"},{\"line\":434,\"text\":\"\\t}\"},{\"line\":435,\"text\":\"\"},{\"line\":436,\"text\":\"\\tpublic function isFileVersionValid()\"},{\"line\":437,\"text\":\"\\t{\"},{\"line\":438,\"text\":\"\\t\\treturn $this->isInstalled()\"},{\"line\":439,\"text\":\"\\t\\t\\t&& $this->isAvailable()\"},{\"line\":440,\"text\":\"\\t\\t\\t&& $this->installedAddOn->version_id == $this->json['version_id'];\"},{\"line\":441,\"text\":\"\\t}\"},{\"line\":442,\"text\":\"\"},{\"line\":443,\"text\":\"\\tpublic function isJsonHashChanged()\"},{\"line\":444,\"text\":\"\\t{\"},{\"line\":445,\"text\":\"\\t\\treturn (\"},{\"line\":446,\"text\":\"\\t\\t\\t$this->isAvailable()\"},{\"line\":447,\"text\":\"\\t\\t\\t&& $this->getJsonHash() !== $this->installedAddOn->json_hash\"},{\"line\":448,\"text\":\"\\t\\t);\"},{\"line\":449,\"text\":\"\\t}\"},{\"line\":450,\"text\":\"\"},{\"line\":451,\"text\":\"\\tpublic function isJsonVersionNewer()\"},{\"line\":452,\"text\":\"\\t{\"},{\"line\":453,\"text\":\"\\t\\treturn ($this->json['version_id'] > $this->installedAddOn->version_id);\"},{\"line\":459,\"text\":\"\\t\\t\\t'version_id' => $this->json['version_id'],\"},{\"line\":460,\"text\":\"\\t\\t\\t'version_string' => $this->json['version_string'],\"},{\"line\":461,\"text\":\"\\t\\t];\"},{\"line\":462,\"text\":\"\\t}\"},{\"line\":463,\"text\":\"\"},{\"line\":464,\"text\":\"\\tpublic function canUpgrade()\"},{\"line\":465,\"text\":\"\\t{\"},{\"line\":466,\"text\":\"\\t\\treturn $this->isInstalled()\"},{\"line\":467,\"text\":\"\\t\\t\\t&& $this->isJsonHashChanged()\"},{\"line\":468,\"text\":\"\\t\\t\\t&& $this->isJsonVersionNewer()\"},{\"line\":469,\"text\":\"\\t\\t\\t&& $this->canEdit();\"},{\"line\":470,\"text\":\"\\t}\"},{\"line\":471,\"text\":\"\"}],\"sha256\":\"0e0346a046fff6bde9850cb53e9dc0d0b5379387029dc16925e562fa141ab422\"},{\"file\":\"src/XF/AddOn/DataManager.php\",\"matches\":[{\"line\":28,\"text\":\"use XF\\\\AddOn\\\\DataType\\\\StylePropertyGroup;\"},{\"line\":29,\"text\":\"use XF\\\\AddOn\\\\DataType\\\\Template;\"},{\"line\":30,\"text\":\"use XF\\\\AddOn\\\\DataType\\\\TemplateModification;\"},{\"line\":31,\"text\":\"use XF\\\\AddOn\\\\DataType\\\\WidgetDefinition;\"},{\"line\":32,\"text\":\"use XF\\\\AddOn\\\\DataType\\\\WidgetPosition;\"},{\"line\":33,\"text\":\"use XF\\\\Finder\\\\AddOnFinder;\"},{\"line\":34,\"text\":\"use XF\\\\Job\\\\AddOnData;\"},{\"line\":35,\"text\":\"use XF\\\\Job\\\\AddOnUninstallData;\"},{\"line\":36,\"text\":\"use XF\\\\Job\\\\Atomic;\"},{\"line\":37,\"text\":\"use XF\\\\Mvc\\\\Entity\\\\Manager;\"},{\"line\":38,\"text\":\"use XF\\\\Repository\\\\ClassExtensionRepository;\"},{\"line\":39,\"text\":\"use XF\\\\Repository\\\\CodeEventListenerRepository;\"},{\"line\":40,\"text\":\"use XF\\\\Repository\\\\ForumTypeRepository;\"},{\"line\":41,\"text\":\"use XF\\\\Repository\\\\PaymentRepository;\"},{\"line\":42,\"text\":\"use XF\\\\Repository\\\\RouteRepository;\"},{\"line\":43,\"text\":\"use XF\\\\Repository\\\\ThreadTypeRepository;\"},{\"line\":44,\"text\":\"use XF\\\\Util\\\\File;\"},{\"line\":45,\"text\":\"\"},{\"line\":46,\"text\":\"class DataManager\"},{\"line\":47,\"text\":\"{\"},{\"line\":48,\"text\":\"\\t/**\"},{\"line\":49,\"text\":\"\\t * @var Manager\"},{\"line\":50,\"text\":\"\\t */\"},{\"line\":132,\"text\":\"\\t\\t$addOnManager = \\\\XF::app()->addOnManager();\"},{\"line\":133,\"text\":\"\"},{\"line\":134,\"text\":\"\\t\\t$addOns = $this->em->getFinder(AddOnFinder::class)->where('active', 1)->fetch();\"},{\"line\":135,\"text\":\"\\t\\tforeach ($addOns AS $addOn)\"},{\"line\":136,\"text\":\"\\t\\t{\"},{\"line\":137,\"text\":\"\\t\\t\\t$activeAddOns[$addOn->addon_id] = $addOn->version_id;\"},{\"line\":138,\"text\":\"\"},{\"line\":139,\"text\":\"\\t\\t\\t$addOnClass = $addOnManager->getById($addOn->addon_id);\"},{\"line\":140,\"text\":\"\\t\\t\\tif ($addOnClass)\"},{\"line\":141,\"text\":\"\\t\\t\\t{\"},{\"line\":142,\"text\":\"\\t\\t\\t\\t$addOnId = $addOn->addon_id;\"},{\"line\":143,\"text\":\"\\t\\t\\t\\t$autoloadPath = $addOnClass->composer_autoload;\"},{\"line\":144,\"text\":\"\"},{\"line\":145,\"text\":\"\\t\\t\\t\\tif (!$autoloadPath)\"},{\"line\":146,\"text\":\"\\t\\t\\t\\t{\"},{\"line\":147,\"text\":\"\\t\\t\\t\\t\\tcontinue;\"},{\"line\":148,\"text\":\"\\t\\t\\t\\t}\"},{\"line\":149,\"text\":\"\"},{\"line\":150,\"text\":\"\\t\\t\\t\\t$addOnAutoload = $addOnManager->getAddOnPath($addOnId) . \\\\XF::$DS . $autoloadPath;\"},{\"line\":151,\"text\":\"\"},{\"line\":152,\"text\":\"\\t\\t\\t\\tif (!$this->checkComposerAutoloadPath('installed.json', $addOnAutoload))\"},{\"line\":153,\"text\":\"\\t\\t\\t\\t{\"},{\"line\":154,\"text\":\"\\t\\t\\t\\t\\tcontinue;\"},{\"line\":266,\"text\":\"\\t\\t}\"},{\"line\":267,\"text\":\"\"},{\"line\":268,\"text\":\"\\t\\t$db->commit();\"},{\"line\":269,\"text\":\"\\t}\"},{\"line\":270,\"text\":\"\"},{\"line\":271,\"text\":\"\\tpublic function enqueueRemoveAddOnData($id)\"},{\"line\":272,\"text\":\"\\t{\"},{\"line\":273,\"text\":\"\\t\\treturn \\\\XF::app()->jobManager()->enqueueUnique($id . 'AddOnUnInstall', AddOnUninstallData::class, [\"},{\"line\":274,\"text\":\"\\t\\t\\t'addon_id' => $id,\"},{\"line\":275,\"text\":\"\\t\\t]);\"},{\"line\":276,\"text\":\"\\t}\"},{\"line\":277,\"text\":\"\"},{\"line\":278,\"text\":\"\\tpublic function finalizeRemoveAddOnData($addOnId)\"},{\"line\":279,\"text\":\"\\t{\"},{\"line\":280,\"text\":\"\\t\\t$simpleCache = \\\\XF::app()->simpleCache();\"},{\"line\":281,\"text\":\"\\t\\t$simpleCache->deleteSet($addOnId);\"},{\"line\":282,\"text\":\"\"},{\"line\":283,\"text\":\"\\t\\t$this->rebuildActiveAddOnCache();\"},{\"line\":284,\"text\":\"\\t}\"},{\"line\":285,\"text\":\"\"},{\"line\":286,\"text\":\"\\t/**\"},{\"line\":287,\"text\":\"\\t * @template T of AbstractDataType\"},{\"line\":288,\"text\":\"\\t *\"}],\"sha256\":\"cfc97d6e825ba983234c86a405bbcf985706575bba6325e253a70c05001338f0\"},{\"file\":\"src/XF/AddOn/StepRunnerUninstallTrait.php\",\"matches\":[{\"line\":3,\"text\":\"namespace XF\\\\AddOn;\"},{\"line\":4,\"text\":\"\"},{\"line\":5,\"text\":\"use function is_array;\"},{\"line\":6,\"text\":\"\"},{\"line\":7,\"text\":\"/**\"},{\"line\":8,\"text\":\" * @property AddOn $addOn\"},{\"line\":9,\"text\":\" */\"},{\"line\":10,\"text\":\"trait StepRunnerUninstallTrait\"},{\"line\":11,\"text\":\"{\"},{\"line\":12,\"text\":\"\\t/**\"},{\"line\":13,\"text\":\"\\t * @param array $stepParams\"},{\"line\":14,\"text\":\"\\t *\"},{\"line\":15,\"text\":\"\\t * @return null|StepResult\"},{\"line\":16,\"text\":\"\\t */\"},{\"line\":17,\"text\":\"\\tpublic function uninstall(array $stepParams = [])\"},{\"line\":18,\"text\":\"\\t{\"},{\"line\":19,\"text\":\"\\t\\t$stepParams = array_replace([\"},{\"line\":20,\"text\":\"\\t\\t\\t'step' => 0,\"},{\"line\":21,\"text\":\"\\t\\t], $stepParams);\"},{\"line\":22,\"text\":\"\"},{\"line\":23,\"text\":\"\\t\\t$step = $stepParams['step'];\"},{\"line\":24,\"text\":\"\\t\\tif (!$step)\"},{\"line\":25,\"text\":\"\\t\\t{\"},{\"line\":26,\"text\":\"\\t\\t\\t$step = $this->getUninstallResumeStep();\"},{\"line\":27,\"text\":\"\\t\\t}\"},{\"line\":28,\"text\":\"\\t\\treturn $this->uninstallStepRunner($step, $stepParams);\"},{\"line\":29,\"text\":\"\\t}\"},{\"line\":30,\"text\":\"\"},{\"line\":31,\"text\":\"\\tprivate function getUninstallResumeStep()\"},{\"line\":32,\"text\":\"\\t{\"},{\"line\":33,\"text\":\"\\t\\t$installedAddOn = $this->addOn->getInstalledAddOn();\"},{\"line\":34,\"text\":\"\\t\\tif ($installedAddOn)\"},{\"line\":35,\"text\":\"\\t\\t{\"},{\"line\":36,\"text\":\"\\t\\t\\t$lastActionStep = $installedAddOn->getLastActionStep('uninstall');\"},{\"line\":37,\"text\":\"\\t\\t\\tif ($lastActionStep)\"},{\"line\":38,\"text\":\"\\t\\t\\t{\"},{\"line\":39,\"text\":\"\\t\\t\\t\\treturn $lastActionStep + 1; // this is the last completed step, so resume with the next\"},{\"line\":40,\"text\":\"\\t\\t\\t}\"},{\"line\":41,\"text\":\"\\t\\t}\"},{\"line\":42,\"text\":\"\"},{\"line\":43,\"text\":\"\\t\\treturn 1;\"},{\"line\":44,\"text\":\"\\t}\"},{\"line\":45,\"text\":\"\"},{\"line\":46,\"text\":\"\\t/**\"},{\"line\":47,\"text\":\"\\t * @param integer $step\"},{\"line\":48,\"text\":\"\\t * @param array $stepParams\"},{\"line\":49,\"text\":\"\\t *\"},{\"line\":50,\"text\":\"\\t * @return null|StepResult\"},{\"line\":51,\"text\":\"\\t */\"},{\"line\":52,\"text\":\"\\tprivate function uninstallStepRunner($step, array $stepParams)\"},{\"line\":53,\"text\":\"\\t{\"},{\"line\":54,\"text\":\"\\t\\t$fnPrefix = 'uninstallStep';\"},{\"line\":55,\"text\":\"\\t\\t$fn = $fnPrefix . $step;\"},{\"line\":56,\"text\":\"\\t\\tif (!method_exists($this, $fn))\"},{\"line\":57,\"text\":\"\\t\\t{\"},{\"line\":58,\"text\":\"\\t\\t\\treturn null;\"},{\"line\":59,\"text\":\"\\t\\t}\"},{\"line\":60,\"text\":\"\"},{\"line\":61,\"text\":\"\\t\\t$result = $this->$fn($stepParams);\"},{\"line\":62,\"text\":\"\\t\\tif ($result === null || $result === true)\"},{\"line\":63,\"text\":\"\\t\\t{\"},{\"line\":64,\"text\":\"\\t\\t\\t$result = new StepResult(true);\"},{\"line\":65,\"text\":\"\\t\\t}\"},{\"line\":66,\"text\":\"\\t\\telse if (is_array($result))\"},{\"line\":67,\"text\":\"\\t\\t{\"},{\"line\":68,\"text\":\"\\t\\t\\t$result = new StepResult(false, $result);\"},{\"line\":69,\"text\":\"\\t\\t}\"},{\"line\":73,\"text\":\"\\t\\t\\tthrow new \\\\LogicException(\\\"Must return a StepResult object\\\");\"},{\"line\":74,\"text\":\"\\t\\t}\"},{\"line\":75,\"text\":\"\"},{\"line\":76,\"text\":\"\\t\\t$result->step = $step;\"},{\"line\":77,\"text\":\"\"},{\"line\":78,\"text\":\"\\t\\tif ($result->complete)\"},{\"line\":79,\"text\":\"\\t\\t{\"},{\"line\":80,\"text\":\"\\t\\t\\t$this->addOn->updatePendingAction('uninstall', $result->step);\"},{\"line\":81,\"text\":\"\"},{\"line\":82,\"text\":\"\\t\\t\\t$nextStep = $step + 1;\"},{\"line\":83,\"text\":\"\\t\\t\\t$nextFn = $fnPrefix . $nextStep;\"},{\"line\":84,\"text\":\"\\t\\t\\tif (!method_exists($this, $nextFn))\"},{\"line\":85,\"text\":\"\\t\\t\\t{\"},{\"line\":86,\"text\":\"\\t\\t\\t\\treturn null;\"},{\"line\":87,\"text\":\"\\t\\t\\t}\"},{\"line\":88,\"text\":\"\"},{\"line\":89,\"text\":\"\\t\\t\\t$result = new StepResult(false, [], $nextStep);\"},{\"line\":90,\"text\":\"\\t\\t}\"},{\"line\":91,\"text\":\"\"},{\"line\":92,\"text\":\"\\t\\treturn $result;\"},{\"line\":93,\"text\":\"\\t}\"},{\"line\":94,\"text\":\"}\"}],\"sha256\":\"e58a9ab9c30e3cf3c41a0be392e8c5ac37f744578f7b91f76d663139649c49a9\"}],\"state\":{\"addon_columns\":[\"addon_id\",\"title\",\"version_string\",\"version_id\",\"json_hash\",\"active\",\"is_legacy\",\"is_processing\",\"last_pending_action\"],\"addon_object\":{\"canUninstall\":{\"exists\":true,\"public\":true,\"required\":0,\"total\":0,\"value\":false},\"class\":\"XF\\\\AddOn\\\\AddOn\",\"getAddOnId\":{\"exists\":true,\"public\":true,\"required\":0,\"total\":0,\"value\":\"Gram/Support\"},\"getInstalledAddOnVersion\":{\"exists\":false},\"getInstalledVersion\":{\"exists\":false},\"getLastPendingAction\":{\"exists\":false},\"getPendingAction\":{\"exists\":false},\"getTitle\":{\"exists\":false},\"isActive\":{\"exists\":true,\"public\":true,\"required\":0,\"total\":0,\"value\":false},\"isInstalled\":{\"exists\":true,\"public\":true,\"required\":0,\"total\":0,\"value\":false},\"isProcessing\":{\"exists\":false},\"present\":true},\"addon_row\":{\"active\":\"1\",\"addon_id\":\"Gram/Support\",\"is_legacy\":\"0\",\"is_processing\":\"1\",\"json_hash\":\"f3804541014a3dfde3b35323475c5dbcbb72ebb0d0c319d66385e9203628724d\",\"last_pending_action\":\"install:1\",\"title\":\"Gram Support\",\"version_id\":\"1000050\",\"version_string\":\"1.0.0 Alpha 3 Unified Fix 3\"},\"board_active\":\"0\",\"error_max\":45,\"errors_after_45\":0,\"manager\":{\"class\":\"XF\\\\AddOn\\\\Manager\",\"getAllAddOns\":{\"exists\":true,\"public\":true,\"required\":0,\"total\":0,\"value\":{\"Gram/Support\":{\"object\":\"XF\\\\AddOn\\\\AddOn\"},\"Newfi/Dogs\":{\"object\":\"XF\\\\AddOn\\\\AddOn\"},\"Newfi/Events\":{\"object\":\"XF\\\\AddOn\\\\AddOn\"},\"Newfi/Portal\":{\"object\":\"XF\\\\AddOn\\\\AddOn\"},\"XFMG\":{\"object\":\"XF\\\\AddOn\\\\AddOn\"},\"XFRM\":{\"object\":\"XF\\\\AddOn\\\\AddOn\"}}},\"getById\":{\"exists\":true,\"public\":true,\"required\":1,\"total\":1},\"getInstalledAddOns\":{\"exists\":true,\"public\":true,\"required\":0,\"total\":0,\"value\":{\"Newfi/Dogs\":{\"object\":\"XF\\\\AddOn\\\\AddOn\"},\"Newfi/Events\":{\"object\":\"XF\\\\AddOn\\\\AddOn\"},\"Newfi/Portal\":{\"object\":\"XF\\\\AddOn\\\\AddOn\"},\"XFMG\":{\"object\":\"XF\\\\AddOn\\\\AddOn\"},\"XFRM\":{\"object\":\"XF\\\\AddOn\\\\AddOn\"}}}},\"registry\":{\"type\":\"object\"},\"registry_rows\":[{\"bytes\":187,\"contains_gram\":true,\"data_key\":\"addOns\",\"sha256\":\"dca4ff8a040ff5651348c60446b8983b7bc1372d3403ee249da526c679c966e4\"},{\"bytes\":6,\"contains_gram\":false,\"data_key\":\"addOnsComposer\",\"sha256\":\"35786c7117b4e38d0f169239752ce71158266ae2f6e4aa230fbbb87bd699c0e3\"}]},\"state_after\":{\"addon_columns\":[\"addon_id\",\"title\",\"version_string\",\"version_id\",\"json_hash\",\"active\",\"is_legacy\",\"is_processing\",\"last_pending_action\"],\"addon_object\":{\"canUninstall\":{\"exists\":true,\"public\":true,\"required\":0,\"total\":0,\"value\":false},\"class\":\"XF\\\\AddOn\\\\AddOn\",\"getAddOnId\":{\"exists\":true,\"public\":true,\"required\":0,\"total\":0,\"value\":\"Gram/Support\"},\"getInstalledAddOnVersion\":{\"exists\":false},\"getInstalledVersion\":{\"exists\":false},\"getLastPendingAction\":{\"exists\":false},\"getPendingAction\":{\"exists\":false},\"getTitle\":{\"exists\":false},\"isActive\":{\"exists\":true,\"public\":true,\"required\":0,\"total\":0,\"value\":false},\"isInstalled\":{\"exists\":true,\"public\":true,\"required\":0,\"total\":0,\"value\":false},\"isProcessing\":{\"exists\":false},\"present\":true},\"addon_row\":{\"active\":\"1\",\"addon_id\":\"Gram/Support\",\"is_legacy\":\"0\",\"is_processing\":\"1\",\"json_hash\":\"f3804541014a3dfde3b35323475c5dbcbb72ebb0d0c319d66385e9203628724d\",\"last_pending_action\":\"install:1\",\"title\":\"Gram Support\",\"version_id\":\"1000050\",\"version_string\":\"1.0.0 Alpha 3 Unified Fix 3\"},\"board_active\":\"0\",\"error_max\":45,\"errors_after_45\":0,\"manager\":{\"class\":\"XF\\\\AddOn\\\\Manager\",\"getAllAddOns\":{\"exists\":true,\"public\":true,\"required\":0,\"total\":0,\"value\":{\"Gram/Support\":{\"object\":\"XF\\\\AddOn\\\\AddOn\"},\"Newfi/Dogs\":{\"object\":\"XF\\\\AddOn\\\\AddOn\"},\"Newfi/Events\":{\"object\":\"XF\\\\AddOn\\\\AddOn\"},\"Newfi/Portal\":{\"object\":\"XF\\\\AddOn\\\\AddOn\"},\"XFMG\":{\"object\":\"XF\\\\AddOn\\\\AddOn\"},\"XFRM\":{\"object\":\"XF\\\\AddOn\\\\AddOn\"}}},\"getById\":{\"exists\":true,\"public\":true,\"required\":1,\"total\":1},\"getInstalledAddOns\":{\"exists\":true,\"public\":true,\"required\":0,\"total\":0,\"value\":{\"Newfi/Dogs\":{\"object\":\"XF\\\\AddOn\\\\AddOn\"},\"Newfi/Events\":{\"object\":\"XF\\\\AddOn\\\\AddOn\"},\"Newfi/Portal\":{\"object\":\"XF\\\\AddOn\\\\AddOn\"},\"XFMG\":{\"object\":\"XF\\\\AddOn\\\\AddOn\"},\"XFRM\":{\"object\":\"XF\\\\AddOn\\\\AddOn\"}}}},\"registry\":{\"type\":\"object\"},\"registry_rows\":[{\"bytes\":187,\"contains_gram\":true,\"data_key\":\"addOns\",\"sha256\":\"dca4ff8a040ff5651348c60446b8983b7bc1372d3403ee249da526c679c966e4\"},{\"bytes\":6,\"contains_gram\":false,\"data_key\":\"addOnsComposer\",\"sha256\":\"35786c7117b4e38d0f169239752ce71158266ae2f6e4aa230fbbb87bd699c0e3\"}]},\"status\":\"OK\",\"uninstall_help\":{\"lines\":[\"Description:\",\"Uninstalls the specified add-on\",\"Usage:\",\"xf:addon-uninstall [options] [--] \",\"xf-addon:uninstall\",\"Arguments:\",\"id Add-On ID\",\"Options:\",\"-f, --force Skip verifying that the add-on is uninstallable\",\"-h, --help Display help for the given command. When no command is given display help for the list command\",\"-q, --quiet Do not output any message\",\"-V, --version Display this application version\",\"--ansi|--no-ansi Force (or disable --no-ansi) ANSI output\",\"-n, --no-interaction Do not ask any interactive question\",\"-v|vv|vvv, --verbose Increase the verbosity of messages: 1 for normal output, 2 for more verbose output and 3 for debug\"],\"rc\":0,\"stderr_sha256\":\"\"}}\nSUPPORT066_HOLDS=[]\nSUPPORT066_DECISION=NARROW_PROCESSING_STATE_CAPTURED\nSUPPORT066_MUTATION_SCOPE=NONE_READ_ONLY\nHOMELAB_RESULT_CONTRACT={\"changes_made\":false,\"command_id\":\"SUPPORT-260909-GRAM-XF-PROCESSING-NARROW-066\",\"rollback_restored\":null,\"rollback_started\":false,\"status\":\"OK\",\"version\":1}\nSUPPORT066_END\n" +} diff --git a/runtime/history/SUPPORT-260909-GRAM-XF-PROCESSING-NARROW-066.txt b/runtime/history/SUPPORT-260909-GRAM-XF-PROCESSING-NARROW-066.txt new file mode 100644 index 00000000..467a711b --- /dev/null +++ b/runtime/history/SUPPORT-260909-GRAM-XF-PROCESSING-NARROW-066.txt @@ -0,0 +1,44 @@ +CHAT_OUTPUT_BEGIN +COMMAND_ID=SUPPORT-260909-GRAM-XF-PROCESSING-NARROW-066 +STATUS=OK +RC=0 +HOST=pve01 +MODE=read-only +COMPONENT=gram-support-processing-narrow +REFERENCE_REGISTER_CHECK=OK +REFERENCE_SHA256=5a3d8e5154c41cb582a4e0aca68090be1f0138918bf82131a948df326f9d8d66 +ERROR_REGISTER_CHECK=OK +ERROR_REGISTER_SHA256=3b09a553ec0f527ed3afeed4753f52a74ee3036045bbfb3c685e9f8af4ba7ba0 +COMMAND_SHA256=b3716049942ceaea06095b5ef78a11b817e642afcc6903f53a48e9f209af6efa +DUPLICATE_FAILED_COMMAND_BLOCKED=false +EXECUTION_STARTED=true +CHANGE_DECLARED=false +RESULT_CONTRACT_VALID=true +RESULT_CONTRACT_STATUS=NOT_APPLICABLE +RESULT_CONTRACT_ERROR=NONE +COMMAND_RC=0 +CHANGES_MADE=false +ROLLBACK_STARTED=false +ROLLBACK_RESTORED=null +MUTATION_OUTCOME=NO_MUTATION +SANITIZED=yes +SECRETS_INCLUDED=no +PRIVATE_ADDRESSES_INCLUDED=no +RAW_EVIDENCE_SHA256=f3bacd113632355b0404ed76453af3e803d539bb8c332baf6b14b126f66f47ee +SANITIZED_OUTPUT_SHA256=f3bacd113632355b0404ed76453af3e803d539bb8c332baf6b14b126f66f47ee +OUTPUT_BEGIN +SUPPORT066_BEGIN +ERROR_REGISTER_CHECK=OK +REFERENCE_CHECK=OK +AUTHORITY_CHECK_SCOPE=READABILITY_ONLY_INCIDENTS_NOT_CLOSED +RUNNER_SHA256=b248a4c32c9cc64e5747e7dce6c7fc0a23f5124a77c71ce72e27a81aceae9d2d +SUPPORT066_QGA_STATE={"exitcode":0,"state":"COMPLETE"} +SUPPORT066_VM211={"command_id":"SUPPORT-260909-GRAM-XF-PROCESSING-NARROW-066","decision":"NARROW_PROCESSING_STATE_CAPTURED","guest":"newfi-staging","holds":[],"identity_ok":true,"probe":{"rc":0,"stderr_sha256":""},"probe_after":{"rc":0,"stderr_sha256":""},"scope":"READ_ONLY_NO_MUTATION","source_evidence":[{"file":"src/XF/Cli/Command/AddOn/AbstractSetupStep.php","matches":[{"line":42,"text":"\t{"},{"line":43,"text":"\t\t$id = $input->getArgument('id');"},{"line":44,"text":""},{"line":45,"text":"\t\t$addOn = $this->checkEditableAddOn($id, $error);"},{"line":46,"text":"\t\tif (!$addOn)"},{"line":47,"text":"\t\t{"},{"line":48,"text":"\t\t\t$output->writeln('' . $error . '');"},{"line":49,"text":"\t\t\treturn 1;"},{"line":50,"text":"\t\t}"},{"line":51,"text":""},{"line":52,"text":"\t\t$setup = $addOn->getSetup();"},{"line":53,"text":""},{"line":54,"text":"\t\tif (!$setup)"},{"line":55,"text":"\t\t{"},{"line":56,"text":"\t\t\t$output->writeln(\"Setup class for add-on could not be found.\");"},{"line":57,"text":"\t\t\treturn 1;"},{"line":58,"text":"\t\t}"},{"line":59,"text":""},{"line":60,"text":"\t\t$step = $input->getArgument('step');"},{"line":61,"text":"\t\t$version = null;"},{"line":62,"text":"\t\t$params = [];"},{"line":63,"text":""},{"line":64,"text":"\t\t$stepType = $this->getStepType();"},{"line":65,"text":"\t\tif ($stepType == 'upgrade')"},{"line":66,"text":"\t\t{"},{"line":67,"text":"\t\t\t$version = $input->getArgument('version');"},{"line":68,"text":"\t\t}"},{"line":69,"text":""},{"line":70,"text":"\t\t$setup->prepareForAction($stepType);"},{"line":71,"text":""},{"line":72,"text":"\t\tdo"},{"line":73,"text":"\t\t{"},{"line":74,"text":"\t\t\t$result = $this->runStep($setup, $output, $stepType, $step, $version, $params);"},{"line":75,"text":"\t\t\tif (!($result instanceof StepResult))"},{"line":76,"text":"\t\t\t{"},{"line":77,"text":"\t\t\t\t$this->clearStatus($output, \"Must return a StepResult object.\");"},{"line":78,"text":"\t\t\t\treturn 1;"},{"line":79,"text":"\t\t\t}"},{"line":80,"text":"\t\t\telse"},{"line":81,"text":"\t\t\t{"},{"line":82,"text":"\t\t\t\tif ($result->complete)"},{"line":83,"text":"\t\t\t\t{"},{"line":84,"text":"\t\t\t\t\t$loop = false;"},{"line":85,"text":"\t\t\t\t}"},{"line":86,"text":"\t\t\t\telse if (is_int($result))"},{"line":87,"text":"\t\t\t\t{"},{"line":88,"text":"\t\t\t\t\t$loop = false;"},{"line":89,"text":"\t\t\t\t}"},{"line":90,"text":"\t\t\t\telse"},{"line":91,"text":"\t\t\t\t{"},{"line":92,"text":"\t\t\t\t\t$params = $result->params;"},{"line":93,"text":"\t\t\t\t\t$loop = true;"},{"line":104,"text":"\tprotected function runStep(AbstractSetup $setup, OutputInterface $output, $stepType, $step, $version = null, array $params = [])"},{"line":105,"text":"\t{"},{"line":106,"text":"\t\t$method = $stepType;"},{"line":107,"text":""},{"line":108,"text":"\t\tswitch ($method)"},{"line":109,"text":"\t\t{"},{"line":110,"text":"\t\t\tcase 'install':"},{"line":111,"text":"\t\t\tcase 'uninstall':"},{"line":112,"text":"\t\t\t\tif ($step)"},{"line":113,"text":"\t\t\t\t{"},{"line":114,"text":"\t\t\t\t\t$method .= 'Step' . $step;"},{"line":115,"text":"\t\t\t\t}"},{"line":116,"text":"\t\t\t\tbreak;"},{"line":117,"text":""},{"line":118,"text":"\t\t\tcase 'upgrade':"},{"line":119,"text":"\t\t\t\tif ($version && $step)"},{"line":120,"text":"\t\t\t\t{"},{"line":121,"text":"\t\t\t\t\t$method .= $version . 'Step' . $step;"},{"line":122,"text":"\t\t\t\t}"},{"line":123,"text":"\t\t\t\tbreak;"},{"line":124,"text":"\t\t}"},{"line":125,"text":""},{"line":126,"text":"\t\tif (!method_exists($setup, $method))"}],"sha256":"86ac6e9eda2202a75f3566a6bf20b14b5cc5171a823e0a23de0e66d0e8c0a8b7"},{"file":"src/XF/Cli/Command/AddOn/Create.php","matches":[{"line":40,"text":"\t\tif ($devOutput->isAddOnSkipped($addOnId))"},{"line":41,"text":"\t\t{"},{"line":42,"text":"\t\t\t$output->writeln(\"Development output for this add-on ID has been disabled. Cannot continue.\");"},{"line":43,"text":"\t\t\tif (strtolower(substr($addOnId, 0, 2)) == 'xf')"},{"line":44,"text":"\t\t\t{"},{"line":45,"text":"\t\t\t\t$output->writeln(\"Note: use of add-on IDs starting with 'xf' is strongly discouraged.\");"},{"line":46,"text":"\t\t\t}"},{"line":47,"text":"\t\t\treturn 1;"},{"line":48,"text":"\t\t}"},{"line":49,"text":""},{"line":50,"text":"\t\t$checkPath = \\XF::getAddOnDirectory();"},{"line":51,"text":""},{"line":52,"text":"\t\t$addOnManager = \\XF::app()->addOnManager();"},{"line":53,"text":"\t\tforeach ($addOnManager->getAllAddOns() AS $existingAddOnId => $existingAddOn)"},{"line":54,"text":"\t\t{"},{"line":55,"text":"\t\t\tif ($existingAddOnId !== $addOnId && strcasecmp($existingAddOnId, $addOnId) === 0)"},{"line":56,"text":"\t\t\t{"},{"line":57,"text":"\t\t\t\t$output->writeln(\"Add-on ID '{$addOnId}' conflicts with existing add-on '{$existingAddOnId}' (case mismatch).\");"},{"line":58,"text":"\t\t\t\treturn 1;"},{"line":59,"text":"\t\t\t}"},{"line":60,"text":"\t\t}"},{"line":61,"text":""},{"line":62,"text":"\t\tif (strpos($addOnId, '/') !== false)"},{"line":63,"text":"\t\t{"},{"line":64,"text":"\t\t\t$addOnIdParts = explode('/', $addOnId);"},{"line":65,"text":"\t\t\t$vendor = reset($addOnIdParts);"},{"line":66,"text":""},{"line":67,"text":"\t\t\tif (file_exists(\\XF::getAddOnDirectory() . \\XF::$DS . $vendor))"},{"line":68,"text":"\t\t\t{"},{"line":69,"text":"\t\t\t\t$checkPath = \\XF::getAddOnDirectory() . \\XF::$DS . $vendor;"},{"line":70,"text":"\t\t\t}"},{"line":71,"text":""},{"line":72,"text":"\t\t\tif ($addOnDir = opendir(\\XF::getAddOnDirectory()))"},{"line":73,"text":"\t\t\t{"},{"line":74,"text":"\t\t\t\twhile (($dir = readdir($addOnDir)) !== false)"},{"line":75,"text":"\t\t\t\t{"},{"line":76,"text":"\t\t\t\t\tif (strcasecmp($dir, $vendor) == 0 && $dir != $vendor)"},{"line":77,"text":"\t\t\t\t\t{"},{"line":78,"text":"\t\t\t\t\t\t$output->writeln(\"The '{$checkPath}' directory conflicts with an existing directory with the same name but a different case.\");"},{"line":79,"text":"\t\t\t\t\t\treturn 1;"},{"line":80,"text":"\t\t\t\t\t}"},{"line":81,"text":"\t\t\t\t}"},{"line":82,"text":"\t\t\t\tclosedir($addOnDir);"},{"line":83,"text":"\t\t\t}"},{"line":84,"text":"\t\t}"},{"line":85,"text":""},{"line":86,"text":"\t\tif (!is_writable($checkPath))"},{"line":87,"text":"\t\t{"},{"line":88,"text":"\t\t\t$checkPathPrintable = str_replace(\\XF::getRootDirectory() . \\XF::$DS, '', $checkPath);"},{"line":89,"text":"\t\t\t$output->writeln(\"The '{$checkPathPrintable}' directory is not writable.\");"},{"line":90,"text":"\t\t\treturn 1;"},{"line":91,"text":"\t\t}"},{"line":92,"text":""},{"line":93,"text":"\t\t$addOnObj = new AddOn($addOnId, \\XF::app()->addOnManager());"},{"line":94,"text":""},{"line":95,"text":"\t\t$jsonPath = $addOnObj->getJsonPath();"},{"line":96,"text":""},{"line":97,"text":"\t\tif (file_exists($jsonPath))"},{"line":98,"text":"\t\t{"},{"line":99,"text":"\t\t\t$output->writeln(\"The addon.json file already exists at {$jsonPath}. You can create the add-on by installing it from the Admin CP.\");"},{"line":100,"text":"\t\t\treturn 1;"},{"line":101,"text":"\t\t}"},{"line":102,"text":""},{"line":103,"text":"\t\t$question = new Question(\"Enter a title: \");"},{"line":104,"text":"\t\t$question->setValidator($this->getAddOnQuestionFieldValidator('title'));"},{"line":105,"text":"\t\t$title = $helper->ask($input, $output, $question);"},{"line":106,"text":"\t\t$output->writeln(\"\");"},{"line":107,"text":""},{"line":108,"text":"\t\t$question = new Question(\"Enter a version ID. This integer will be used for internal version comparisons. Each release of your add-on should increase this number: \");"},{"line":109,"text":"\t\t$question->setValidator(function ($value)"},{"line":110,"text":"\t\t{"},{"line":111,"text":"\t\t\tif (!preg_match('/^[0-9]+$/', $value))"},{"line":112,"text":"\t\t\t{"},{"line":113,"text":"\t\t\t\tthrow new \\InvalidArgumentException(\"The version ID should contain numeric values only.\");"},{"line":114,"text":"\t\t\t}"},{"line":115,"text":"\t\t\treturn $value;"},{"line":170,"text":""},{"line":171,"text":"\t\t$output->writeln(\"\");"},{"line":172,"text":""},{"line":173,"text":"\t\t$addOn->preSave();"},{"line":174,"text":"\t\tif ($errors = $addOn->getErrors())"},{"line":175,"text":"\t\t{"},{"line":176,"text":"\t\t\t$output->writeln(\"An unexpected error occurred while saving the add-on: \" . reset($errors) . \"\");"},{"line":177,"text":"\t\t\treturn 1;"},{"line":178,"text":"\t\t}"},{"line":179,"text":""},{"line":180,"text":"\t\t$addOn->save();"},{"line":181,"text":""},{"line":182,"text":"\t\tFile::createDirectory($addOnObj->getAddOnDirectory(), false);"},{"line":183,"text":""},{"line":184,"text":"\t\t$json = ["},{"line":185,"text":"\t\t\t'title' => $addOn->title,"},{"line":186,"text":"\t\t\t'version_string' => $addOn->version_string,"},{"line":187,"text":"\t\t\t'version_id' => intval($addOn->version_id),"},{"line":188,"text":"\t\t];"},{"line":189,"text":"\t\tif ($legacyAddOnId)"},{"line":190,"text":"\t\t{"},{"line":191,"text":"\t\t\t$json['legacy_addon_id'] = $legacyAddOnId;"},{"line":192,"text":"\t\t}"},{"line":220,"text":"\t\t\t\t$setupContent = <<< SETUP"}],"sha256":"4ff8f77caa12327158b9a6ba6ed2ffe85b959011279be5a70a8b3e77f75204f5"},{"file":"src/XF/Cli/Command/AddOn/UninstallStep.php","matches":[{"line":1,"text":"addArgument("},{"line":17,"text":"\t\t\t'step',"},{"line":18,"text":"\t\t\tInputArgument::REQUIRED,"},{"line":19,"text":"\t\t\t'The step number to run.'"},{"line":20,"text":"\t\t);"},{"line":21,"text":"\t}"},{"line":22,"text":"}"}],"sha256":"d69b287acd3ea5c02bf23492e1bdef465fb75f22f00b45acdb4ffafe547260e5"},{"file":"src/XF/AddOn/AbstractSetup.php","matches":[{"line":32,"text":"\tabstract public function upgrade(array $stepParams = []);"},{"line":33,"text":""},{"line":34,"text":"\t/**"},{"line":35,"text":"\t * @param array $stepParams"},{"line":36,"text":"\t *"},{"line":37,"text":"\t * @return null|StepResult"},{"line":38,"text":"\t */"},{"line":39,"text":"\tabstract public function uninstall(array $stepParams = []);"},{"line":40,"text":""},{"line":41,"text":"\tpublic function __construct(AddOn $addOn, App $app)"},{"line":42,"text":"\t{"},{"line":43,"text":"\t\t$this->addOn = $addOn;"},{"line":44,"text":"\t\t$this->app = $app;"},{"line":45,"text":"\t}"},{"line":46,"text":""},{"line":47,"text":"\t/**"},{"line":48,"text":"\t * Perform additional requirement checks."},{"line":49,"text":"\t *"},{"line":50,"text":"\t * @param list $errors Errors will block the setup from continuing"},{"line":51,"text":"\t * @param list $warnings Warnings will be displayed but allow the user to continue setup"},{"line":52,"text":"\t *"},{"line":53,"text":"\t * @return void"},{"line":54,"text":"\t */"},{"line":86,"text":"\t\t$this->app->jobManager()->enqueueUnique($uniqueId, FileCleanUp::class, ["},{"line":87,"text":"\t\t\t'addon_id' => $addOn->addon_id,"},{"line":88,"text":"\t\t], false);"},{"line":89,"text":"\t}"},{"line":90,"text":""},{"line":91,"text":"\tpublic function prepareForAction($action)"},{"line":92,"text":"\t{"},{"line":93,"text":"\t\tif ($action == 'uninstall')"},{"line":94,"text":"\t\t{"},{"line":95,"text":"\t\t\t\\XF::db()->ignoreLegacyTableWriteError(true);"},{"line":96,"text":"\t\t}"},{"line":97,"text":"\t}"},{"line":98,"text":""},{"line":99,"text":"\t/**"},{"line":100,"text":"\t * @param $sql"},{"line":101,"text":"\t * @param array $bind"},{"line":102,"text":"\t * @param bool $suppressAll"},{"line":103,"text":"\t *"},{"line":104,"text":"\t * @return bool|AbstractStatement"},{"line":105,"text":"\t * @throws Exception"},{"line":106,"text":"\t */"},{"line":107,"text":"\tprotected function query($sql, $bind = [], $suppressAll = false)"},{"line":108,"text":"\t{"}],"sha256":"6bdd3fe834e15b963a52c9357f54262f2d12f3c7c3686fc31333b549cddf2d88"},{"file":"src/XF/AddOn/AddOn.php","matches":[{"line":332,"text":"\t\t\t\t}"},{"line":333,"text":"\t\t\t}"},{"line":334,"text":"\t\t}"},{"line":335,"text":""},{"line":336,"text":"\t\treturn $this->setup;"},{"line":337,"text":"\t}"},{"line":338,"text":""},{"line":339,"text":"\tpublic function isInstalled()"},{"line":340,"text":"\t{"},{"line":341,"text":"\t\tif ($this->installedAddOn === null)"},{"line":342,"text":"\t\t{"},{"line":343,"text":"\t\t\treturn false;"},{"line":344,"text":"\t\t}"},{"line":345,"text":""},{"line":346,"text":"\t\t$lastAction = $this->installedAddOn->getLastActionStep('install');"},{"line":347,"text":"\t\tif ($lastAction !== null)"},{"line":348,"text":"\t\t{"},{"line":349,"text":"\t\t\t// we haven't completed the install steps yet, don't consider as installed"},{"line":350,"text":"\t\t\treturn false;"},{"line":351,"text":"\t\t}"},{"line":352,"text":""},{"line":353,"text":"\t\treturn true;"},{"line":354,"text":"\t}"},{"line":355,"text":""},{"line":356,"text":"\tpublic function isActive()"},{"line":357,"text":"\t{"},{"line":358,"text":"\t\treturn $this->isInstalled()"},{"line":359,"text":"\t\t\t&& $this->installedAddOn->active;"},{"line":360,"text":"\t}"},{"line":361,"text":""},{"line":362,"text":"\tpublic function isLegacy()"},{"line":363,"text":"\t{"},{"line":364,"text":"\t\treturn $this->isInstalled()"},{"line":365,"text":"\t\t\t&& $this->installedAddOn->is_legacy;"},{"line":366,"text":"\t}"},{"line":367,"text":""},{"line":368,"text":"\tpublic function isDevOutputAvailable()"},{"line":369,"text":"\t{"},{"line":370,"text":"\t\treturn \\XF::app()->developmentOutput()->isAddOnOutputAvailable($this->getAddOnId());"},{"line":371,"text":"\t}"},{"line":372,"text":""},{"line":373,"text":"\tpublic function hasMissingFiles()"},{"line":374,"text":"\t{"},{"line":375,"text":"\t\treturn count($this->missingFiles) > 0;"},{"line":376,"text":"\t}"},{"line":377,"text":""},{"line":378,"text":"\tpublic function hasPendingChanges()"},{"line":379,"text":"\t{"},{"line":380,"text":"\t\treturn $this->isInstalled()"},{"line":381,"text":"\t\t\t&& !$this->isLegacy()"},{"line":382,"text":"\t\t\t&& ("},{"line":383,"text":"\t\t\t\t!$this->isFileVersionValid()"},{"line":384,"text":"\t\t\t\t|| $this->isJsonHashChanged()"},{"line":385,"text":"\t\t\t);"},{"line":386,"text":"\t}"},{"line":387,"text":""},{"line":388,"text":"\tpublic function hasFaIcon()"},{"line":389,"text":"\t{"},{"line":390,"text":"\t\treturn ("},{"line":391,"text":"\t\t\t$this->icon"},{"line":392,"text":"\t\t\t&& !$this->hasIcon()"},{"line":393,"text":"\t\t\t&& preg_match('#^(fa-|fa[a-z] )#', $this->icon)"},{"line":394,"text":"\t\t);"},{"line":395,"text":"\t}"},{"line":431,"text":"\tpublic function isAvailable()"},{"line":432,"text":"\t{"},{"line":433,"text":"\t\treturn count($this->missingFiles) == 0;"},{"line":434,"text":"\t}"},{"line":435,"text":""},{"line":436,"text":"\tpublic function isFileVersionValid()"},{"line":437,"text":"\t{"},{"line":438,"text":"\t\treturn $this->isInstalled()"},{"line":439,"text":"\t\t\t&& $this->isAvailable()"},{"line":440,"text":"\t\t\t&& $this->installedAddOn->version_id == $this->json['version_id'];"},{"line":441,"text":"\t}"},{"line":442,"text":""},{"line":443,"text":"\tpublic function isJsonHashChanged()"},{"line":444,"text":"\t{"},{"line":445,"text":"\t\treturn ("},{"line":446,"text":"\t\t\t$this->isAvailable()"},{"line":447,"text":"\t\t\t&& $this->getJsonHash() !== $this->installedAddOn->json_hash"},{"line":448,"text":"\t\t);"},{"line":449,"text":"\t}"},{"line":450,"text":""},{"line":451,"text":"\tpublic function isJsonVersionNewer()"},{"line":452,"text":"\t{"},{"line":453,"text":"\t\treturn ($this->json['version_id'] > $this->installedAddOn->version_id);"},{"line":459,"text":"\t\t\t'version_id' => $this->json['version_id'],"},{"line":460,"text":"\t\t\t'version_string' => $this->json['version_string'],"},{"line":461,"text":"\t\t];"},{"line":462,"text":"\t}"},{"line":463,"text":""},{"line":464,"text":"\tpublic function canUpgrade()"},{"line":465,"text":"\t{"},{"line":466,"text":"\t\treturn $this->isInstalled()"},{"line":467,"text":"\t\t\t&& $this->isJsonHashChanged()"},{"line":468,"text":"\t\t\t&& $this->isJsonVersionNewer()"},{"line":469,"text":"\t\t\t&& $this->canEdit();"},{"line":470,"text":"\t}"},{"line":471,"text":""}],"sha256":"0e0346a046fff6bde9850cb53e9dc0d0b5379387029dc16925e562fa141ab422"},{"file":"src/XF/AddOn/DataManager.php","matches":[{"line":28,"text":"use XF\\AddOn\\DataType\\StylePropertyGroup;"},{"line":29,"text":"use XF\\AddOn\\DataType\\Template;"},{"line":30,"text":"use XF\\AddOn\\DataType\\TemplateModification;"},{"line":31,"text":"use XF\\AddOn\\DataType\\WidgetDefinition;"},{"line":32,"text":"use XF\\AddOn\\DataType\\WidgetPosition;"},{"line":33,"text":"use XF\\Finder\\AddOnFinder;"},{"line":34,"text":"use XF\\Job\\AddOnData;"},{"line":35,"text":"use XF\\Job\\AddOnUninstallData;"},{"line":36,"text":"use XF\\Job\\Atomic;"},{"line":37,"text":"use XF\\Mvc\\Entity\\Manager;"},{"line":38,"text":"use XF\\Repository\\ClassExtensionRepository;"},{"line":39,"text":"use XF\\Repository\\CodeEventListenerRepository;"},{"line":40,"text":"use XF\\Repository\\ForumTypeRepository;"},{"line":41,"text":"use XF\\Repository\\PaymentRepository;"},{"line":42,"text":"use XF\\Repository\\RouteRepository;"},{"line":43,"text":"use XF\\Repository\\ThreadTypeRepository;"},{"line":44,"text":"use XF\\Util\\File;"},{"line":45,"text":""},{"line":46,"text":"class DataManager"},{"line":47,"text":"{"},{"line":48,"text":"\t/**"},{"line":49,"text":"\t * @var Manager"},{"line":50,"text":"\t */"},{"line":132,"text":"\t\t$addOnManager = \\XF::app()->addOnManager();"},{"line":133,"text":""},{"line":134,"text":"\t\t$addOns = $this->em->getFinder(AddOnFinder::class)->where('active', 1)->fetch();"},{"line":135,"text":"\t\tforeach ($addOns AS $addOn)"},{"line":136,"text":"\t\t{"},{"line":137,"text":"\t\t\t$activeAddOns[$addOn->addon_id] = $addOn->version_id;"},{"line":138,"text":""},{"line":139,"text":"\t\t\t$addOnClass = $addOnManager->getById($addOn->addon_id);"},{"line":140,"text":"\t\t\tif ($addOnClass)"},{"line":141,"text":"\t\t\t{"},{"line":142,"text":"\t\t\t\t$addOnId = $addOn->addon_id;"},{"line":143,"text":"\t\t\t\t$autoloadPath = $addOnClass->composer_autoload;"},{"line":144,"text":""},{"line":145,"text":"\t\t\t\tif (!$autoloadPath)"},{"line":146,"text":"\t\t\t\t{"},{"line":147,"text":"\t\t\t\t\tcontinue;"},{"line":148,"text":"\t\t\t\t}"},{"line":149,"text":""},{"line":150,"text":"\t\t\t\t$addOnAutoload = $addOnManager->getAddOnPath($addOnId) . \\XF::$DS . $autoloadPath;"},{"line":151,"text":""},{"line":152,"text":"\t\t\t\tif (!$this->checkComposerAutoloadPath('installed.json', $addOnAutoload))"},{"line":153,"text":"\t\t\t\t{"},{"line":154,"text":"\t\t\t\t\tcontinue;"},{"line":266,"text":"\t\t}"},{"line":267,"text":""},{"line":268,"text":"\t\t$db->commit();"},{"line":269,"text":"\t}"},{"line":270,"text":""},{"line":271,"text":"\tpublic function enqueueRemoveAddOnData($id)"},{"line":272,"text":"\t{"},{"line":273,"text":"\t\treturn \\XF::app()->jobManager()->enqueueUnique($id . 'AddOnUnInstall', AddOnUninstallData::class, ["},{"line":274,"text":"\t\t\t'addon_id' => $id,"},{"line":275,"text":"\t\t]);"},{"line":276,"text":"\t}"},{"line":277,"text":""},{"line":278,"text":"\tpublic function finalizeRemoveAddOnData($addOnId)"},{"line":279,"text":"\t{"},{"line":280,"text":"\t\t$simpleCache = \\XF::app()->simpleCache();"},{"line":281,"text":"\t\t$simpleCache->deleteSet($addOnId);"},{"line":282,"text":""},{"line":283,"text":"\t\t$this->rebuildActiveAddOnCache();"},{"line":284,"text":"\t}"},{"line":285,"text":""},{"line":286,"text":"\t/**"},{"line":287,"text":"\t * @template T of AbstractDataType"},{"line":288,"text":"\t *"}],"sha256":"cfc97d6e825ba983234c86a405bbcf985706575bba6325e253a70c05001338f0"},{"file":"src/XF/AddOn/StepRunnerUninstallTrait.php","matches":[{"line":3,"text":"namespace XF\\AddOn;"},{"line":4,"text":""},{"line":5,"text":"use function is_array;"},{"line":6,"text":""},{"line":7,"text":"/**"},{"line":8,"text":" * @property AddOn $addOn"},{"line":9,"text":" */"},{"line":10,"text":"trait StepRunnerUninstallTrait"},{"line":11,"text":"{"},{"line":12,"text":"\t/**"},{"line":13,"text":"\t * @param array $stepParams"},{"line":14,"text":"\t *"},{"line":15,"text":"\t * @return null|StepResult"},{"line":16,"text":"\t */"},{"line":17,"text":"\tpublic function uninstall(array $stepParams = [])"},{"line":18,"text":"\t{"},{"line":19,"text":"\t\t$stepParams = array_replace(["},{"line":20,"text":"\t\t\t'step' => 0,"},{"line":21,"text":"\t\t], $stepParams);"},{"line":22,"text":""},{"line":23,"text":"\t\t$step = $stepParams['step'];"},{"line":24,"text":"\t\tif (!$step)"},{"line":25,"text":"\t\t{"},{"line":26,"text":"\t\t\t$step = $this->getUninstallResumeStep();"},{"line":27,"text":"\t\t}"},{"line":28,"text":"\t\treturn $this->uninstallStepRunner($step, $stepParams);"},{"line":29,"text":"\t}"},{"line":30,"text":""},{"line":31,"text":"\tprivate function getUninstallResumeStep()"},{"line":32,"text":"\t{"},{"line":33,"text":"\t\t$installedAddOn = $this->addOn->getInstalledAddOn();"},{"line":34,"text":"\t\tif ($installedAddOn)"},{"line":35,"text":"\t\t{"},{"line":36,"text":"\t\t\t$lastActionStep = $installedAddOn->getLastActionStep('uninstall');"},{"line":37,"text":"\t\t\tif ($lastActionStep)"},{"line":38,"text":"\t\t\t{"},{"line":39,"text":"\t\t\t\treturn $lastActionStep + 1; // this is the last completed step, so resume with the next"},{"line":40,"text":"\t\t\t}"},{"line":41,"text":"\t\t}"},{"line":42,"text":""},{"line":43,"text":"\t\treturn 1;"},{"line":44,"text":"\t}"},{"line":45,"text":""},{"line":46,"text":"\t/**"},{"line":47,"text":"\t * @param integer $step"},{"line":48,"text":"\t * @param array $stepParams"},{"line":49,"text":"\t *"},{"line":50,"text":"\t * @return null|StepResult"},{"line":51,"text":"\t */"},{"line":52,"text":"\tprivate function uninstallStepRunner($step, array $stepParams)"},{"line":53,"text":"\t{"},{"line":54,"text":"\t\t$fnPrefix = 'uninstallStep';"},{"line":55,"text":"\t\t$fn = $fnPrefix . $step;"},{"line":56,"text":"\t\tif (!method_exists($this, $fn))"},{"line":57,"text":"\t\t{"},{"line":58,"text":"\t\t\treturn null;"},{"line":59,"text":"\t\t}"},{"line":60,"text":""},{"line":61,"text":"\t\t$result = $this->$fn($stepParams);"},{"line":62,"text":"\t\tif ($result === null || $result === true)"},{"line":63,"text":"\t\t{"},{"line":64,"text":"\t\t\t$result = new StepResult(true);"},{"line":65,"text":"\t\t}"},{"line":66,"text":"\t\telse if (is_array($result))"},{"line":67,"text":"\t\t{"},{"line":68,"text":"\t\t\t$result = new StepResult(false, $result);"},{"line":69,"text":"\t\t}"},{"line":73,"text":"\t\t\tthrow new \\LogicException(\"Must return a StepResult object\");"},{"line":74,"text":"\t\t}"},{"line":75,"text":""},{"line":76,"text":"\t\t$result->step = $step;"},{"line":77,"text":""},{"line":78,"text":"\t\tif ($result->complete)"},{"line":79,"text":"\t\t{"},{"line":80,"text":"\t\t\t$this->addOn->updatePendingAction('uninstall', $result->step);"},{"line":81,"text":""},{"line":82,"text":"\t\t\t$nextStep = $step + 1;"},{"line":83,"text":"\t\t\t$nextFn = $fnPrefix . $nextStep;"},{"line":84,"text":"\t\t\tif (!method_exists($this, $nextFn))"},{"line":85,"text":"\t\t\t{"},{"line":86,"text":"\t\t\t\treturn null;"},{"line":87,"text":"\t\t\t}"},{"line":88,"text":""},{"line":89,"text":"\t\t\t$result = new StepResult(false, [], $nextStep);"},{"line":90,"text":"\t\t}"},{"line":91,"text":""},{"line":92,"text":"\t\treturn $result;"},{"line":93,"text":"\t}"},{"line":94,"text":"}"}],"sha256":"e58a9ab9c30e3cf3c41a0be392e8c5ac37f744578f7b91f76d663139649c49a9"}],"state":{"addon_columns":["addon_id","title","version_string","version_id","json_hash","active","is_legacy","is_processing","last_pending_action"],"addon_object":{"canUninstall":{"exists":true,"public":true,"required":0,"total":0,"value":false},"class":"XF\\AddOn\\AddOn","getAddOnId":{"exists":true,"public":true,"required":0,"total":0,"value":"Gram/Support"},"getInstalledAddOnVersion":{"exists":false},"getInstalledVersion":{"exists":false},"getLastPendingAction":{"exists":false},"getPendingAction":{"exists":false},"getTitle":{"exists":false},"isActive":{"exists":true,"public":true,"required":0,"total":0,"value":false},"isInstalled":{"exists":true,"public":true,"required":0,"total":0,"value":false},"isProcessing":{"exists":false},"present":true},"addon_row":{"active":"1","addon_id":"Gram/Support","is_legacy":"0","is_processing":"1","json_hash":"f3804541014a3dfde3b35323475c5dbcbb72ebb0d0c319d66385e9203628724d","last_pending_action":"install:1","title":"Gram Support","version_id":"1000050","version_string":"1.0.0 Alpha 3 Unified Fix 3"},"board_active":"0","error_max":45,"errors_after_45":0,"manager":{"class":"XF\\AddOn\\Manager","getAllAddOns":{"exists":true,"public":true,"required":0,"total":0,"value":{"Gram/Support":{"object":"XF\\AddOn\\AddOn"},"Newfi/Dogs":{"object":"XF\\AddOn\\AddOn"},"Newfi/Events":{"object":"XF\\AddOn\\AddOn"},"Newfi/Portal":{"object":"XF\\AddOn\\AddOn"},"XFMG":{"object":"XF\\AddOn\\AddOn"},"XFRM":{"object":"XF\\AddOn\\AddOn"}}},"getById":{"exists":true,"public":true,"required":1,"total":1},"getInstalledAddOns":{"exists":true,"public":true,"required":0,"total":0,"value":{"Newfi/Dogs":{"object":"XF\\AddOn\\AddOn"},"Newfi/Events":{"object":"XF\\AddOn\\AddOn"},"Newfi/Portal":{"object":"XF\\AddOn\\AddOn"},"XFMG":{"object":"XF\\AddOn\\AddOn"},"XFRM":{"object":"XF\\AddOn\\AddOn"}}}},"registry":{"type":"object"},"registry_rows":[{"bytes":187,"contains_gram":true,"data_key":"addOns","sha256":"dca4ff8a040ff5651348c60446b8983b7bc1372d3403ee249da526c679c966e4"},{"bytes":6,"contains_gram":false,"data_key":"addOnsComposer","sha256":"35786c7117b4e38d0f169239752ce71158266ae2f6e4aa230fbbb87bd699c0e3"}]},"state_after":{"addon_columns":["addon_id","title","version_string","version_id","json_hash","active","is_legacy","is_processing","last_pending_action"],"addon_object":{"canUninstall":{"exists":true,"public":true,"required":0,"total":0,"value":false},"class":"XF\\AddOn\\AddOn","getAddOnId":{"exists":true,"public":true,"required":0,"total":0,"value":"Gram/Support"},"getInstalledAddOnVersion":{"exists":false},"getInstalledVersion":{"exists":false},"getLastPendingAction":{"exists":false},"getPendingAction":{"exists":false},"getTitle":{"exists":false},"isActive":{"exists":true,"public":true,"required":0,"total":0,"value":false},"isInstalled":{"exists":true,"public":true,"required":0,"total":0,"value":false},"isProcessing":{"exists":false},"present":true},"addon_row":{"active":"1","addon_id":"Gram/Support","is_legacy":"0","is_processing":"1","json_hash":"f3804541014a3dfde3b35323475c5dbcbb72ebb0d0c319d66385e9203628724d","last_pending_action":"install:1","title":"Gram Support","version_id":"1000050","version_string":"1.0.0 Alpha 3 Unified Fix 3"},"board_active":"0","error_max":45,"errors_after_45":0,"manager":{"class":"XF\\AddOn\\Manager","getAllAddOns":{"exists":true,"public":true,"required":0,"total":0,"value":{"Gram/Support":{"object":"XF\\AddOn\\AddOn"},"Newfi/Dogs":{"object":"XF\\AddOn\\AddOn"},"Newfi/Events":{"object":"XF\\AddOn\\AddOn"},"Newfi/Portal":{"object":"XF\\AddOn\\AddOn"},"XFMG":{"object":"XF\\AddOn\\AddOn"},"XFRM":{"object":"XF\\AddOn\\AddOn"}}},"getById":{"exists":true,"public":true,"required":1,"total":1},"getInstalledAddOns":{"exists":true,"public":true,"required":0,"total":0,"value":{"Newfi/Dogs":{"object":"XF\\AddOn\\AddOn"},"Newfi/Events":{"object":"XF\\AddOn\\AddOn"},"Newfi/Portal":{"object":"XF\\AddOn\\AddOn"},"XFMG":{"object":"XF\\AddOn\\AddOn"},"XFRM":{"object":"XF\\AddOn\\AddOn"}}}},"registry":{"type":"object"},"registry_rows":[{"bytes":187,"contains_gram":true,"data_key":"addOns","sha256":"dca4ff8a040ff5651348c60446b8983b7bc1372d3403ee249da526c679c966e4"},{"bytes":6,"contains_gram":false,"data_key":"addOnsComposer","sha256":"35786c7117b4e38d0f169239752ce71158266ae2f6e4aa230fbbb87bd699c0e3"}]},"status":"OK","uninstall_help":{"lines":["Description:","Uninstalls the specified add-on","Usage:","xf:addon-uninstall [options] [--] ","xf-addon:uninstall","Arguments:","id Add-On ID","Options:","-f, --force Skip verifying that the add-on is uninstallable","-h, --help Display help for the given command. When no command is given display help for the list command","-q, --quiet Do not output any message","-V, --version Display this application version","--ansi|--no-ansi Force (or disable --no-ansi) ANSI output","-n, --no-interaction Do not ask any interactive question","-v|vv|vvv, --verbose Increase the verbosity of messages: 1 for normal output, 2 for more verbose output and 3 for debug"],"rc":0,"stderr_sha256":""}} +SUPPORT066_HOLDS=[] +SUPPORT066_DECISION=NARROW_PROCESSING_STATE_CAPTURED +SUPPORT066_MUTATION_SCOPE=NONE_READ_ONLY +HOMELAB_RESULT_CONTRACT={"changes_made":false,"command_id":"SUPPORT-260909-GRAM-XF-PROCESSING-NARROW-066","rollback_restored":null,"rollback_started":false,"status":"OK","version":1} +SUPPORT066_END + +OUTPUT_END +CHAT_OUTPUT_END diff --git a/runtime/latest.json b/runtime/latest.json index f7360079..bb970264 100644 --- a/runtime/latest.json +++ b/runtime/latest.json @@ -1,19 +1,19 @@ { "schema_version": 1, "channel": "homelab-runtime", - "command_id": "SUPPORT-260909-GRAM-XF-PROCESSING-RCA-065", + "command_id": "SUPPORT-260909-GRAM-XF-PROCESSING-NARROW-066", "status": "OK", "rc": 0, "host": "pve01", "mode": "read-only", - "component": "gram-support-processing-state-rca", - "started_at_utc": "2026-09-09T12:45:51Z", - "finished_at_utc": "2026-09-09T12:45:54Z", + "component": "gram-support-processing-narrow", + "started_at_utc": "2026-09-09T12:52:31Z", + "finished_at_utc": "2026-09-09T12:52:33Z", "reference_register_checked": true, "reference_sha256": "5a3d8e5154c41cb582a4e0aca68090be1f0138918bf82131a948df326f9d8d66", "error_register_checked": true, "error_register_sha256": "3b09a553ec0f527ed3afeed4753f52a74ee3036045bbfb3c685e9f8af4ba7ba0", - "command_sha256": "58650c7036826de2b367e43288c37a4bd74fa37fd38895b6cd899c5b17b53b68", + "command_sha256": "b3716049942ceaea06095b5ef78a11b817e642afcc6903f53a48e9f209af6efa", "duplicate_failed_command_blocked": false, "block_reason": null, "execution_started": true, @@ -30,9 +30,9 @@ "secrets_included": false, "private_addresses_included": false, "raw_evidence_retained_locally": true, - "raw_evidence_sha256": "9fff9616621e2e34c86e9d1b10d3848cacb6aea9487d9a67a849be45c240506d", - "sanitized_output_sha256": "9fff9616621e2e34c86e9d1b10d3848cacb6aea9487d9a67a849be45c240506d", + "raw_evidence_sha256": "f3bacd113632355b0404ed76453af3e803d539bb8c332baf6b14b126f66f47ee", + "sanitized_output_sha256": "f3bacd113632355b0404ed76453af3e803d539bb8c332baf6b14b126f66f47ee", "output_truncated_in_json": false, "full_sanitized_output_url": "https://git.gram1.ru/.well-known/homelab-runtime/latest.txt", - "output": "SUPPORT065_BEGIN\nERROR_REGISTER_CHECK=OK\nREFERENCE_CHECK=OK\nAUTHORITY_CHECK_SCOPE=READABILITY_ONLY_INCIDENTS_NOT_CLOSED\nRUNNER_SHA256=b248a4c32c9cc64e5747e7dce6c7fc0a23f5124a77c71ce72e27a81aceae9d2d\nSUPPORT065_QGA_STATE={\"exitcode\":0,\"state\":\"COMPLETE\"}\nSUPPORT065_VM211={\"addon_list\":{\"rc\":0,\"stderr\":\"\",\"stdout\":\"{\\n \\\"addons\\\": [\\n {\\n \\\"addon_id\\\": \\\"Newfi\\\\/Dogs\\\",\\n \\\"title\\\": \\\"Newfi Dogs\\\",\\n \\\"version_string\\\": \\\"1.0.0 Alpha 1\\\",\\n \\\"version_id\\\": 1000010,\\n \\\"active\\\": true,\\n \\\"legacy\\\": false,\\n \\\"is_processing\\\": false,\\n \\\"last_pending_action\\\": null,\\n \\\"developer\\\": \\\"Newfi\\\",\\n \\\"path\\\": \\\"\\\\/var\\\\/www\\\\/forums\\\\/newfi\\\\/public\\\\/src\\\\/addons\\\\/Newfi\\\\/Dogs\\\"\\n },\\n {\\n \\\"addon_id\\\": \\\"Newfi\\\\/Events\\\",\\n \\\"title\\\": \\\"Newfi Events\\\",\\n \\\"version_string\\\": \\\"1.0.0 Alpha 1\\\",\\n \\\"version_id\\\": 1000010,\\n \\\"active\\\": true,\\n \\\"legacy\\\": false,\\n \\\"is_processing\\\": false,\\n \\\"last_pending_action\\\": null,\\n \\\"developer\\\": \\\"Newfi\\\",\\n \\\"path\\\": \\\"\\\\/var\\\\/www\\\\/forums\\\\/newfi\\\\/public\\\\/src\\\\/addons\\\\/Newfi\\\\/Events\\\"\\n },\\n {\\n \\\"addon_id\\\": \\\"Newfi\\\\/Portal\\\",\\n \\\"title\\\": \\\"Newfi Portal\\\",\\n \\\"version_string\\\": \\\"1.0.0 Alpha 1\\\",\\n \\\"version_id\\\": 1000010,\\n \\\"active\\\": true,\\n \\\"legacy\\\": false,\\n \\\"is_processing\\\": false,\\n \\\"last_pending_action\\\": null,\\n \\\"developer\\\": \\\"Newfi\\\",\\n \\\"path\\\": \\\"\\\\/var\\\\/www\\\\/forums\\\\/newfi\\\\/public\\\\/src\\\\/addons\\\\/Newfi\\\\/Portal\\\"\\n },\\n {\\n \\\"addon_id\\\": \\\"XFMG\\\",\\n \\\"title\\\": \\\"XenForo Media Gallery\\\",\\n \\\"version_string\\\": \\\"2.3.11\\\",\\n \\\"version_id\\\": 902031170,\\n \\\"active\\\": true,\\n \\\"legacy\\\": false,\\n \\\"is_processing\\\": false,\\n \\\"last_pending_action\\\": null,\\n \\\"developer\\\": \\\"XenForo Ltd.\\\",\\n \\\"path\\\": \\\"\\\\/var\\\\/www\\\\/forums\\\\/newfi\\\\/public\\\\/src\\\\/addons\\\\/XFMG\\\"\\n },\\n {\\n \\\"addon_id\\\": \\\"XFRM\\\",\\n \\\"title\\\": \\\"XenForo Resource Manager\\\",\\n \\\"version_string\\\": \\\"2.3.11\\\",\\n \\\"version_id\\\": 2031170,\\n \\\"active\\\": true,\\n \\\"legacy\\\": false,\\n \\\"is_processing\\\": false,\\n \\\"last_pending_action\\\": null,\\n \\\"developer\\\": \\\"XenForo Ltd.\\\",\\n \\\"path\\\": \\\"\\\\/var\\\\/www\\\\/forums\\\\/newfi\\\\/public\\\\/src\\\\/addons\\\\/XFRM\\\"\\n }\\n ],\\n \\\"summary\\\": {\\n \\\"total\\\": 5,\\n \\\"active\\\": 5,\\n \\\"inactive\\\": 0\\n }\\n}\"},\"command_id\":\"SUPPORT-260909-GRAM-XF-PROCESSING-RCA-065\",\"decision\":\"PROCESSING_STATE_AND_UNINSTALL_SOURCE_CAPTURED\",\"guest\":\"newfi-staging\",\"holds\":[],\"identity_ok\":true,\"list_help\":{\"rc\":0,\"stderr\":\"\",\"stdout\":\"Description:\\n Lists installed add-ons\\n\\nUsage:\\n xf:addon-list [options]\\n xf-addon:list\\n\\nOptions:\\n --active Only show active add-ons\\n --inactive Only show inactive add-ons\\n --json Output as JSON\\n -h, --help Display help for the given command. When no command is given display help for the list command\\n -q, --quiet Do not output any message\\n -V, --version Display this application version\\n --ansi|--no-ansi Force (or disable --no-ansi) ANSI output\\n -n, --no-interaction Do not ask any interactive question\\n -v|vv|vvv, --verbose Increase the verbosity of messages: 1 for normal output, 2 for more verbose output and 3 for debug\"},\"php_state\":{\"data\":{\"addon_columns\":[\"addon_id\",\"title\",\"version_string\",\"version_id\",\"json_hash\",\"active\",\"is_legacy\",\"is_processing\",\"last_pending_action\"],\"addon_row\":{\"active\":\"1\",\"addon_id\":\"Gram/Support\",\"is_legacy\":\"0\",\"is_processing\":\"1\",\"json_hash\":\"f3804541014a3dfde3b35323475c5dbcbb72ebb0d0c319d66385e9203628724d\",\"last_pending_action\":\"install:1\",\"title\":\"Gram Support\",\"version_id\":\"1000050\",\"version_string\":\"1.0.0 Alpha 3 Unified Fix 3\"},\"board_active\":\"0\",\"error_max\":45,\"errors_after_45\":0,\"manager_class\":\"XF\\\\AddOn\\\\Manager\",\"manager_getById\":{\"canUninstall\":false,\"class\":\"XF\\\\AddOn\\\\AddOn\",\"getSetup\":\"Gram\\\\Support\\\\Setup\",\"isActive\":false,\"isInstalled\":false},\"manager_methods\":{\"getAllAddOns\":{\"public\":true,\"required\":0,\"total\":0},\"getById\":{\"public\":true,\"required\":1,\"total\":1},\"getInstalledAddOns\":{\"public\":true,\"required\":0,\"total\":0}}},\"rc\":0,\"stderr_sha256\":\"\"},\"scope\":\"READ_ONLY_NO_MUTATION\",\"source_evidence\":[{\"file\":\"src/XF/Cli/Command/AddOn/UninstallStep.php\",\"matches\":[{\"line\":1,\"text\":\"addArgument(\"},{\"line\":17,\"text\":\"\\t\\t\\t'step',\"},{\"line\":18,\"text\":\"\\t\\t\\tInputArgument::REQUIRED,\"},{\"line\":19,\"text\":\"\\t\\t\\t'The step number to run.'\"},{\"line\":20,\"text\":\"\\t\\t);\"},{\"line\":21,\"text\":\"\\t}\"},{\"line\":22,\"text\":\"}\"}],\"sha256\":\"d69b287acd3ea5c02bf23492e1bdef465fb75f22f00b45acdb4ffafe547260e5\"},{\"file\":\"src/XF/Cli/Command/AddOnUninstall.php\",\"matches\":[{\"line\":2,\"text\":\"\"},{\"line\":3,\"text\":\"namespace XF\\\\Cli\\\\Command;\"},{\"line\":4,\"text\":\"\"},{\"line\":5,\"text\":\"use Symfony\\\\Component\\\\Console\\\\Helper\\\\QuestionHelper;\"},{\"line\":6,\"text\":\"use Symfony\\\\Component\\\\Console\\\\Input\\\\InputArgument;\"},{\"line\":7,\"text\":\"use Symfony\\\\Component\\\\Console\\\\Input\\\\InputInterface;\"},{\"line\":8,\"text\":\"use Symfony\\\\Component\\\\Console\\\\Input\\\\InputOption;\"},{\"line\":9,\"text\":\"use Symfony\\\\Component\\\\Console\\\\Output\\\\OutputInterface;\"},{\"line\":10,\"text\":\"use Symfony\\\\Component\\\\Console\\\\Question\\\\ConfirmationQuestion;\"},{\"line\":11,\"text\":\"\"},{\"line\":12,\"text\":\"class AddOnUninstall extends AbstractCommand\"},{\"line\":13,\"text\":\"{\"},{\"line\":14,\"text\":\"\\tuse AddOnActionTrait;\"},{\"line\":15,\"text\":\"\\tuse JobRunnerTrait;\"},{\"line\":16,\"text\":\"\"},{\"line\":17,\"text\":\"\\tprotected function configure()\"},{\"line\":18,\"text\":\"\\t{\"},{\"line\":19,\"text\":\"\\t\\t$this\"},{\"line\":20,\"text\":\"\\t\\t\\t->setName('xf:addon-uninstall')\"},{\"line\":21,\"text\":\"\\t\\t\\t->setAliases(['xf-addon:uninstall'])\"},{\"line\":22,\"text\":\"\\t\\t\\t->setDescription('Uninstalls the specified add-on')\"},{\"line\":23,\"text\":\"\\t\\t\\t->addArgument(\"},{\"line\":24,\"text\":\"\\t\\t\\t\\t'id',\"},{\"line\":25,\"text\":\"\\t\\t\\t\\tInputArgument::REQUIRED,\"},{\"line\":26,\"text\":\"\\t\\t\\t\\t'Add-On ID'\"},{\"line\":27,\"text\":\"\\t\\t\\t)\"},{\"line\":28,\"text\":\"\\t\\t\\t->addOption(\"},{\"line\":29,\"text\":\"\\t\\t\\t\\t'force',\"},{\"line\":30,\"text\":\"\\t\\t\\t\\t'f',\"},{\"line\":31,\"text\":\"\\t\\t\\t\\tInputOption::VALUE_NONE,\"},{\"line\":32,\"text\":\"\\t\\t\\t\\t'Skip verifying that the add-on is uninstallable'\"},{\"line\":33,\"text\":\"\\t\\t\\t);\"},{\"line\":34,\"text\":\"\\t}\"},{\"line\":35,\"text\":\"\"},{\"line\":36,\"text\":\"\\tprotected function execute(InputInterface $input, OutputInterface $output)\"},{\"line\":37,\"text\":\"\\t{\"},{\"line\":38,\"text\":\"\\t\\t$id = $input->getArgument('id');\"},{\"line\":39,\"text\":\"\"},{\"line\":40,\"text\":\"\\t\\t$addOn = $this->checkInstalledAddOn($id, $error);\"},{\"line\":41,\"text\":\"\\t\\tif (!$addOn)\"},{\"line\":42,\"text\":\"\\t\\t{\"},{\"line\":43,\"text\":\"\\t\\t\\t$output->writeln('' . $error . '');\"},{\"line\":44,\"text\":\"\\t\\t\\treturn 1;\"},{\"line\":45,\"text\":\"\\t\\t}\"},{\"line\":46,\"text\":\"\"},{\"line\":47,\"text\":\"\\t\\tif (!$addOn->canUninstall() && !$input->getOption('force'))\"},{\"line\":48,\"text\":\"\\t\\t{\"},{\"line\":49,\"text\":\"\\t\\t\\t$output->writeln(\\\"\\\" . \\\\XF::phrase('this_add_on_cannot_be_uninstalled_like_files_missing') . \\\"\\\");\"},{\"line\":50,\"text\":\"\\t\\t\\treturn 1;\"},{\"line\":51,\"text\":\"\\t\\t}\"},{\"line\":52,\"text\":\"\"},{\"line\":53,\"text\":\"\\t\\t/** @var QuestionHelper $helper */\"},{\"line\":54,\"text\":\"\\t\\t$helper = $this->getHelper('question');\"},{\"line\":55,\"text\":\"\"},{\"line\":56,\"text\":\"\\t\\t$question = new ConfirmationQuestion(\\\"\\\" . \\\\XF::phrase('please_confirm_that_you_want_to_uninstall_following_add_on') . ': (' . $addOn->title . ' ' . $addOn->version_string . \\\") (y/n)\\\");\"},{\"line\":57,\"text\":\"\\t\\t$response = $helper->ask($input, $output, $question);\"},{\"line\":58,\"text\":\"\\t\\tif (!$response)\"},{\"line\":59,\"text\":\"\\t\\t{\"},{\"line\":60,\"text\":\"\\t\\t\\treturn 1;\"},{\"line\":61,\"text\":\"\\t\\t}\"},{\"line\":62,\"text\":\"\"},{\"line\":63,\"text\":\"\\t\\t// make sure any errors get logged here\"},{\"line\":64,\"text\":\"\\t\\t\\\\XF::app()->error()->setIgnorePendingUpgrade(true);\"},{\"line\":65,\"text\":\"\"},{\"line\":66,\"text\":\"\\t\\t$addOn->preUninstall();\"},{\"line\":67,\"text\":\"\"},{\"line\":68,\"text\":\"\\t\\t$this->runSubAction($output, $addOn, 'uninstall');\"},{\"line\":69,\"text\":\"\\t\\t$this->runSubAction($output, $addOn, 'uninstall-data');\"},{\"line\":70,\"text\":\"\\t\\t$this->runSubAction($output, $addOn, 'post-uninstall');\"},{\"line\":71,\"text\":\"\"},{\"line\":72,\"text\":\"\\t\\treturn 0;\"},{\"line\":73,\"text\":\"\\t}\"},{\"line\":74,\"text\":\"}\"}],\"sha256\":\"6dc768f60efd4af161b549cd54c01ae8922326cf7fd230b8ef93403bf8dba90c\"},{\"file\":\"src/XF/AddOn/AddOn.php\",\"matches\":[{\"line\":45,\"text\":\"\\t/**\"},{\"line\":46,\"text\":\"\\t * @var \\\\XF\\\\Entity\\\\AddOn\"},{\"line\":47,\"text\":\"\\t */\"},{\"line\":48,\"text\":\"\\tprotected $installedAddOn;\"},{\"line\":49,\"text\":\"\"},{\"line\":50,\"text\":\"\\t/**\"},{\"line\":51,\"text\":\"\\t * @var AbstractSetup\"},{\"line\":52,\"text\":\"\\t */\"},{\"line\":53,\"text\":\"\\tprotected $setup;\"},{\"line\":54,\"text\":\"\"},{\"line\":55,\"text\":\"\\tprotected $addOnId;\"},{\"line\":56,\"text\":\"\\tprotected $legacyAddOnId;\"},{\"line\":57,\"text\":\"\"},{\"line\":58,\"text\":\"\\tprotected $addOnDir;\"},{\"line\":59,\"text\":\"\\tprotected $buildDir;\"},{\"line\":60,\"text\":\"\\tprotected $dataDir;\"},{\"line\":61,\"text\":\"\\tprotected $filesDir;\"},{\"line\":62,\"text\":\"\\tprotected $outputDir;\"},{\"line\":63,\"text\":\"\\tprotected $releasesDir;\"},{\"line\":64,\"text\":\"\"},{\"line\":65,\"text\":\"\\tprotected $jsonPath;\"},{\"line\":66,\"text\":\"\\tprotected $json = [];\"},{\"line\":67,\"text\":\"\"},{\"line\":68,\"text\":\"\\tprotected $buildJsonPath;\"},{\"line\":69,\"text\":\"\\tprotected $buildJson = [];\"},{\"line\":70,\"text\":\"\"},{\"line\":71,\"text\":\"\\tprotected $missingFiles = [];\"},{\"line\":72,\"text\":\"\"},{\"line\":73,\"text\":\"\\tprotected $addOnHashes;\"},{\"line\":74,\"text\":\"\"},{\"line\":75,\"text\":\"\\tpublic function __construct($addOnOrId, Manager $manager)\"},{\"line\":76,\"text\":\"\\t{\"},{\"line\":77,\"text\":\"\\t\\t$this->manager = $manager;\"},{\"line\":78,\"text\":\"\"},{\"line\":79,\"text\":\"\\t\\tif ($addOnOrId instanceof \\\\XF\\\\Entity\\\\AddOn)\"},{\"line\":80,\"text\":\"\\t\\t{\"},{\"line\":81,\"text\":\"\\t\\t\\t$this->installedAddOn = $addOnOrId;\"},{\"line\":82,\"text\":\"\\t\\t\\t$this->addOnId = $addOnOrId->addon_id;\"},{\"line\":83,\"text\":\"\\t\\t}\"},{\"line\":84,\"text\":\"\\t\\telse\"},{\"line\":85,\"text\":\"\\t\\t{\"},{\"line\":86,\"text\":\"\\t\\t\\t$this->addOnId = $addOnOrId;\"},{\"line\":87,\"text\":\"\\t\\t}\"},{\"line\":88,\"text\":\"\"},{\"line\":89,\"text\":\"\\t\\t$ds = \\\\XF::$DS;\"},{\"line\":90,\"text\":\"\"},{\"line\":91,\"text\":\"\\t\\t$this->addOnDir = \\\\XF::getAddOnDirectory() . $ds . $this->prepareAddOnIdForPath();\"},{\"line\":92,\"text\":\"\"},{\"line\":93,\"text\":\"\\t\\t// Resolve symlinks to ensure consistent path handling\"},{\"line\":94,\"text\":\"\\t\\t$realAddOnDir = realpath($this->addOnDir);\"},{\"line\":95,\"text\":\"\\t\\tif ($realAddOnDir !== false)\"},{\"line\":96,\"text\":\"\\t\\t{\"},{\"line\":97,\"text\":\"\\t\\t\\t$this->addOnDir = $realAddOnDir;\"},{\"line\":98,\"text\":\"\\t\\t}\"},{\"line\":99,\"text\":\"\"},{\"line\":100,\"text\":\"\\t\\t$this->buildDir = $this->addOnDir . $ds . '_build';\"},{\"line\":101,\"text\":\"\\t\\t$this->dataDir = $this->addOnDir . $ds . '_data';\"},{\"line\":102,\"text\":\"\\t\\t$this->filesDir = $this->addOnDir . $ds . '_files';\"},{\"line\":103,\"text\":\"\\t\\t$this->outputDir = $this->addOnDir . $ds . '_output';\"},{\"line\":104,\"text\":\"\\t\\t$this->releasesDir = $this->addOnDir . $ds . '_releases';\"},{\"line\":105,\"text\":\"\"},{\"line\":106,\"text\":\"\\t\\t$this->jsonPath = $this->addOnDir . $ds . 'addon.json';\"},{\"line\":107,\"text\":\"\\t\\tif (file_exists($this->jsonPath))\"},{\"line\":108,\"text\":\"\\t\\t{\"},{\"line\":109,\"text\":\"\\t\\t\\t$this->json = $this->prepareJsonFile(\"},{\"line\":110,\"text\":\"\\t\\t\\t\\tjson_decode(file_get_contents($this->jsonPath), true) ?: []\"},{\"line\":111,\"text\":\"\\t\\t\\t);\"},{\"line\":112,\"text\":\"\\t\\t}\"},{\"line\":113,\"text\":\"\\t\\telse\"},{\"line\":114,\"text\":\"\\t\\t{\"},{\"line\":115,\"text\":\"\\t\\t\\t$this->missingFiles[] = 'addon.json';\"},{\"line\":116,\"text\":\"\\t\\t}\"},{\"line\":117,\"text\":\"\"},{\"line\":118,\"text\":\"\\t\\tif (!$this->installedAddOn && !empty($this->json['legacy_addon_id']))\"},{\"line\":119,\"text\":\"\\t\\t{\"},{\"line\":120,\"text\":\"\\t\\t\\t$this->legacyAddOnId = $this->json['legacy_addon_id'];\"},{\"line\":121,\"text\":\"\\t\\t\\t$this->installedAddOn = \\\\XF::em()->find(\\\\XF\\\\Entity\\\\AddOn::class, $this->legacyAddOnId);\"},{\"line\":122,\"text\":\"\\t\\t}\"},{\"line\":123,\"text\":\"\"},{\"line\":124,\"text\":\"\\t\\t$this->buildJsonPath = $this->addOnDir . $ds . 'build.json';\"},{\"line\":125,\"text\":\"\\t\\t$this->buildJson = [\"},{\"line\":126,\"text\":\"\\t\\t\\t'additional_files' => [],\"},{\"line\":127,\"text\":\"\\t\\t\\t'minify' => [],\"},{\"line\":128,\"text\":\"\\t\\t\\t'rollup' => [],\"},{\"line\":129,\"text\":\"\\t\\t\\t'exec' => [],\"},{\"line\":130,\"text\":\"\\t\\t];\"},{\"line\":131,\"text\":\"\\t\\tif (file_exists($this->buildJsonPath))\"},{\"line\":132,\"text\":\"\\t\\t{\"},{\"line\":133,\"text\":\"\\t\\t\\t$buildJson = @json_decode(file_get_contents($this->buildJsonPath), true);\"},{\"line\":134,\"text\":\"\"},{\"line\":135,\"text\":\"\\t\\t\\t$this->buildJson = array_replace(\"},{\"line\":136,\"text\":\"\\t\\t\\t\\t$this->buildJson,\"},{\"line\":137,\"text\":\"\\t\\t\\t\\t$buildJson ?: []\"},{\"line\":138,\"text\":\"\\t\\t\\t);\"},{\"line\":139,\"text\":\"\\t\\t}\"},{\"line\":140,\"text\":\"\\t}\"},{\"line\":141,\"text\":\"\"},{\"line\":142,\"text\":\"\\tpublic function getInstalledAddOn()\"},{\"line\":143,\"text\":\"\\t{\"},{\"line\":144,\"text\":\"\\t\\treturn $this->installedAddOn;\"},{\"line\":145,\"text\":\"\\t}\"},{\"line\":146,\"text\":\"\"},{\"line\":147,\"text\":\"\\tpublic function getAddOnId()\"},{\"line\":148,\"text\":\"\\t{\"},{\"line\":149,\"text\":\"\\t\\treturn $this->addOnId;\"},{\"line\":150,\"text\":\"\\t}\"},{\"line\":151,\"text\":\"\"},{\"line\":152,\"text\":\"\\tpublic function getAddOnIdUrl()\"},{\"line\":153,\"text\":\"\\t{\"},{\"line\":154,\"text\":\"\\t\\treturn \\\\XF::app()->repository(AddOnRepository::class)->convertAddOnIdToUrlVersion($this->getAddOnId());\"},{\"line\":155,\"text\":\"\\t}\"},{\"line\":156,\"text\":\"\"},{\"line\":157,\"text\":\"\\tpublic function prepareVersionForFilename()\"},{\"line\":158,\"text\":\"\\t{\"},{\"line\":159,\"text\":\"\\t\\t$versionString = preg_replace('/[^a-z0-9-_. ]/i', '', $this->version_string);\"},{\"line\":160,\"text\":\"\\t\\treturn trim(preg_replace('/\\\\s{2,}/', ' ', $versionString));\"},{\"line\":161,\"text\":\"\\t}\"},{\"line\":162,\"text\":\"\"},{\"line\":163,\"text\":\"\\tpublic function prepareAddOnIdForFilename()\"},{\"line\":164,\"text\":\"\\t{\"},{\"line\":165,\"text\":\"\\t\\tif (strpos($this->addOnId, '/') !== false)\"},{\"line\":166,\"text\":\"\\t\\t{\"},{\"line\":167,\"text\":\"\\t\\t\\treturn str_replace('/', '-', $this->addOnId);\"},{\"line\":168,\"text\":\"\\t\\t}\"},{\"line\":169,\"text\":\"\\t\\telse\"},{\"line\":170,\"text\":\"\\t\\t{\"},{\"line\":171,\"text\":\"\\t\\t\\treturn $this->addOnId;\"},{\"line\":172,\"text\":\"\\t\\t}\"},{\"line\":173,\"text\":\"\\t}\"},{\"line\":174,\"text\":\"\"},{\"line\":175,\"text\":\"\\tpublic function prepareAddOnIdForPath()\"},{\"line\":176,\"text\":\"\\t{\"},{\"line\":177,\"text\":\"\\t\\tif (strpos($this->addOnId, '/') !== false)\"},{\"line\":178,\"text\":\"\\t\\t{\"},{\"line\":179,\"text\":\"\\t\\t\\treturn str_replace('/', \\\\XF::$DS, $this->addOnId);\"},{\"line\":180,\"text\":\"\\t\\t}\"},{\"line\":181,\"text\":\"\\t\\telse\"},{\"line\":182,\"text\":\"\\t\\t{\"},{\"line\":183,\"text\":\"\\t\\t\\treturn $this->addOnId;\"},{\"line\":184,\"text\":\"\\t\\t}\"},{\"line\":185,\"text\":\"\\t}\"},{\"line\":186,\"text\":\"\"},{\"line\":187,\"text\":\"\\tpublic function prepareAddOnIdForClass()\"},{\"line\":188,\"text\":\"\\t{\"},{\"line\":189,\"text\":\"\\t\\tif (strpos($this->addOnId, '/') !== false)\"},{\"line\":190,\"text\":\"\\t\\t{\"},{\"line\":191,\"text\":\"\\t\\t\\treturn str_replace('/', '\\\\\\\\', $this->addOnId);\"},{\"line\":192,\"text\":\"\\t\\t}\"},{\"line\":193,\"text\":\"\\t\\telse\"},{\"line\":194,\"text\":\"\\t\\t{\"},{\"line\":195,\"text\":\"\\t\\t\\treturn $this->addOnId;\"},{\"line\":196,\"text\":\"\\t\\t}\"},{\"line\":197,\"text\":\"\\t}\"},{\"line\":198,\"text\":\"\"},{\"line\":199,\"text\":\"\\tpublic function getMissingFiles()\"},{\"line\":200,\"text\":\"\\t{\"},{\"line\":201,\"text\":\"\\t\\treturn $this->missingFiles;\"},{\"line\":202,\"text\":\"\\t}\"},{\"line\":203,\"text\":\"\"},{\"line\":204,\"text\":\"\\tpublic function getAddOnDirectory()\"},{\"line\":205,\"text\":\"\\t{\"},{\"line\":206,\"text\":\"\\t\\treturn $this->addOnDir;\"},{\"line\":207,\"text\":\"\\t}\"},{\"line\":208,\"text\":\"\"},{\"line\":209,\"text\":\"\\tpublic function getBuildDirectory()\"},{\"line\":210,\"text\":\"\\t{\"},{\"line\":211,\"text\":\"\\t\\treturn $this->buildDir;\"},{\"line\":212,\"text\":\"\\t}\"},{\"line\":213,\"text\":\"\"},{\"line\":214,\"text\":\"\\tpublic function getDataDirectory()\"},{\"line\":215,\"text\":\"\\t{\"},{\"line\":216,\"text\":\"\\t\\treturn $this->dataDir;\"},{\"line\":221,\"text\":\"\\t\\treturn $this->filesDir;\"},{\"line\":222,\"text\":\"\\t}\"},{\"line\":223,\"text\":\"\"},{\"line\":224,\"text\":\"\\tpublic function getReleasesDirectory()\"},{\"line\":225,\"text\":\"\\t{\"},{\"line\":226,\"text\":\"\\t\\treturn $this->releasesDir;\"},{\"line\":227,\"text\":\"\\t}\"},{\"line\":228,\"text\":\"\"}],\"sha256\":\"0e0346a046fff6bde9850cb53e9dc0d0b5379387029dc16925e562fa141ab422\"},{\"file\":\"src/XF/AddOn/StepRunnerUninstallTrait.php\",\"matches\":[{\"line\":1,\"text\":\" 0,\"},{\"line\":21,\"text\":\"\\t\\t], $stepParams);\"},{\"line\":22,\"text\":\"\"},{\"line\":23,\"text\":\"\\t\\t$step = $stepParams['step'];\"},{\"line\":24,\"text\":\"\\t\\tif (!$step)\"},{\"line\":25,\"text\":\"\\t\\t{\"},{\"line\":26,\"text\":\"\\t\\t\\t$step = $this->getUninstallResumeStep();\"},{\"line\":27,\"text\":\"\\t\\t}\"},{\"line\":28,\"text\":\"\\t\\treturn $this->uninstallStepRunner($step, $stepParams);\"},{\"line\":29,\"text\":\"\\t}\"},{\"line\":30,\"text\":\"\"},{\"line\":31,\"text\":\"\\tprivate function getUninstallResumeStep()\"},{\"line\":32,\"text\":\"\\t{\"},{\"line\":33,\"text\":\"\\t\\t$installedAddOn = $this->addOn->getInstalledAddOn();\"},{\"line\":34,\"text\":\"\\t\\tif ($installedAddOn)\"},{\"line\":35,\"text\":\"\\t\\t{\"},{\"line\":36,\"text\":\"\\t\\t\\t$lastActionStep = $installedAddOn->getLastActionStep('uninstall');\"},{\"line\":37,\"text\":\"\\t\\t\\tif ($lastActionStep)\"},{\"line\":38,\"text\":\"\\t\\t\\t{\"},{\"line\":39,\"text\":\"\\t\\t\\t\\treturn $lastActionStep + 1; // this is the last completed step, so resume with the next\"},{\"line\":40,\"text\":\"\\t\\t\\t}\"},{\"line\":41,\"text\":\"\\t\\t}\"},{\"line\":42,\"text\":\"\"},{\"line\":43,\"text\":\"\\t\\treturn 1;\"},{\"line\":44,\"text\":\"\\t}\"},{\"line\":45,\"text\":\"\"},{\"line\":46,\"text\":\"\\t/**\"},{\"line\":47,\"text\":\"\\t * @param integer $step\"},{\"line\":48,\"text\":\"\\t * @param array $stepParams\"},{\"line\":49,\"text\":\"\\t *\"},{\"line\":50,\"text\":\"\\t * @return null|StepResult\"},{\"line\":51,\"text\":\"\\t */\"},{\"line\":52,\"text\":\"\\tprivate function uninstallStepRunner($step, array $stepParams)\"},{\"line\":53,\"text\":\"\\t{\"},{\"line\":54,\"text\":\"\\t\\t$fnPrefix = 'uninstallStep';\"},{\"line\":55,\"text\":\"\\t\\t$fn = $fnPrefix . $step;\"},{\"line\":56,\"text\":\"\\t\\tif (!method_exists($this, $fn))\"},{\"line\":57,\"text\":\"\\t\\t{\"},{\"line\":58,\"text\":\"\\t\\t\\treturn null;\"},{\"line\":59,\"text\":\"\\t\\t}\"},{\"line\":60,\"text\":\"\"},{\"line\":61,\"text\":\"\\t\\t$result = $this->$fn($stepParams);\"},{\"line\":62,\"text\":\"\\t\\tif ($result === null || $result === true)\"},{\"line\":63,\"text\":\"\\t\\t{\"},{\"line\":64,\"text\":\"\\t\\t\\t$result = new StepResult(true);\"},{\"line\":65,\"text\":\"\\t\\t}\"},{\"line\":66,\"text\":\"\\t\\telse if (is_array($result))\"},{\"line\":67,\"text\":\"\\t\\t{\"},{\"line\":68,\"text\":\"\\t\\t\\t$result = new StepResult(false, $result);\"},{\"line\":69,\"text\":\"\\t\\t}\"},{\"line\":70,\"text\":\"\"},{\"line\":71,\"text\":\"\\t\\tif (!($result instanceof StepResult))\"},{\"line\":72,\"text\":\"\\t\\t{\"},{\"line\":73,\"text\":\"\\t\\t\\tthrow new \\\\LogicException(\\\"Must return a StepResult object\\\");\"},{\"line\":74,\"text\":\"\\t\\t}\"},{\"line\":75,\"text\":\"\"},{\"line\":76,\"text\":\"\\t\\t$result->step = $step;\"},{\"line\":77,\"text\":\"\"},{\"line\":78,\"text\":\"\\t\\tif ($result->complete)\"},{\"line\":79,\"text\":\"\\t\\t{\"},{\"line\":80,\"text\":\"\\t\\t\\t$this->addOn->updatePendingAction('uninstall', $result->step);\"},{\"line\":81,\"text\":\"\"},{\"line\":82,\"text\":\"\\t\\t\\t$nextStep = $step + 1;\"},{\"line\":83,\"text\":\"\\t\\t\\t$nextFn = $fnPrefix . $nextStep;\"},{\"line\":84,\"text\":\"\\t\\t\\tif (!method_exists($this, $nextFn))\"},{\"line\":85,\"text\":\"\\t\\t\\t{\"},{\"line\":86,\"text\":\"\\t\\t\\t\\treturn null;\"},{\"line\":87,\"text\":\"\\t\\t\\t}\"},{\"line\":88,\"text\":\"\"},{\"line\":89,\"text\":\"\\t\\t\\t$result = new StepResult(false, [], $nextStep);\"},{\"line\":90,\"text\":\"\\t\\t}\"},{\"line\":91,\"text\":\"\"},{\"line\":92,\"text\":\"\\t\\treturn $result;\"},{\"line\":93,\"text\":\"\\t}\"},{\"line\":94,\"text\":\"}\"}],\"sha256\":\"e58a9ab9c30e3cf3c41a0be392e8c5ac37f744578f7b91f76d663139649c49a9\"}],\"state_after\":{\"addon_columns\":[\"addon_id\",\"title\",\"version_string\",\"version_id\",\"json_hash\",\"active\",\"is_legacy\",\"is_processing\",\"last_pending_action\"],\"addon_row\":{\"active\":\"1\",\"addon_id\":\"Gram/Support\",\"is_legacy\":\"0\",\"is_processing\":\"1\",\"json_hash\":\"f3804541014a3dfde3b35323475c5dbcbb72ebb0d0c319d66385e9203628724d\",\"last_pending_action\":\"install:1\",\"title\":\"Gram Support\",\"version_id\":\"1000050\",\"version_string\":\"1.0.0 Alpha 3 Unified Fix 3\"},\"board_active\":\"0\",\"error_max\":45,\"errors_after_45\":0,\"manager_class\":\"XF\\\\AddOn\\\\Manager\",\"manager_getById\":{\"canUninstall\":false,\"class\":\"XF\\\\AddOn\\\\AddOn\",\"getSetup\":\"Gram\\\\Support\\\\Setup\",\"isActive\":false,\"isInstalled\":false},\"manager_methods\":{\"getAllAddOns\":{\"public\":true,\"required\":0,\"total\":0},\"getById\":{\"public\":true,\"required\":1,\"total\":1},\"getInstalledAddOns\":{\"public\":true,\"required\":0,\"total\":0}}},\"status\":\"OK\",\"uninstall_help\":{\"rc\":0,\"stderr\":\"\",\"stdout\":\"Description:\\n Uninstalls the specified add-on\\n\\nUsage:\\n xf:addon-uninstall [options] [--] \\n xf-addon:uninstall\\n\\nArguments:\\n id Add-On ID\\n\\nOptions:\\n -f, --force Skip verifying that the add-on is uninstallable\\n -h, --help Display help for the given command. When no command is given display help for the list command\\n -q, --quiet Do not output any message\\n -V, --version Display this application version\\n --ansi|--no-ansi Force (or disable --no-ansi) ANSI output\\n -n, --no-interaction Do not ask any interactive question\\n -v|vv|vvv, --verbose Increase the verbosity of messages: 1 for normal output, 2 for more verbose output and 3 for debug\"}}\nSUPPORT065_HOLDS=[]\nSUPPORT065_DECISION=PROCESSING_STATE_AND_UNINSTALL_SOURCE_CAPTURED\nSUPPORT065_MUTATION_SCOPE=NONE_READ_ONLY\nHOMELAB_RESULT_CONTRACT={\"changes_made\":false,\"command_id\":\"SUPPORT-260909-GRAM-XF-PROCESSING-RCA-065\",\"rollback_restored\":null,\"rollback_started\":false,\"status\":\"OK\",\"version\":1}\nSUPPORT065_END\n" + "output": "SUPPORT066_BEGIN\nERROR_REGISTER_CHECK=OK\nREFERENCE_CHECK=OK\nAUTHORITY_CHECK_SCOPE=READABILITY_ONLY_INCIDENTS_NOT_CLOSED\nRUNNER_SHA256=b248a4c32c9cc64e5747e7dce6c7fc0a23f5124a77c71ce72e27a81aceae9d2d\nSUPPORT066_QGA_STATE={\"exitcode\":0,\"state\":\"COMPLETE\"}\nSUPPORT066_VM211={\"command_id\":\"SUPPORT-260909-GRAM-XF-PROCESSING-NARROW-066\",\"decision\":\"NARROW_PROCESSING_STATE_CAPTURED\",\"guest\":\"newfi-staging\",\"holds\":[],\"identity_ok\":true,\"probe\":{\"rc\":0,\"stderr_sha256\":\"\"},\"probe_after\":{\"rc\":0,\"stderr_sha256\":\"\"},\"scope\":\"READ_ONLY_NO_MUTATION\",\"source_evidence\":[{\"file\":\"src/XF/Cli/Command/AddOn/AbstractSetupStep.php\",\"matches\":[{\"line\":42,\"text\":\"\\t{\"},{\"line\":43,\"text\":\"\\t\\t$id = $input->getArgument('id');\"},{\"line\":44,\"text\":\"\"},{\"line\":45,\"text\":\"\\t\\t$addOn = $this->checkEditableAddOn($id, $error);\"},{\"line\":46,\"text\":\"\\t\\tif (!$addOn)\"},{\"line\":47,\"text\":\"\\t\\t{\"},{\"line\":48,\"text\":\"\\t\\t\\t$output->writeln('' . $error . '');\"},{\"line\":49,\"text\":\"\\t\\t\\treturn 1;\"},{\"line\":50,\"text\":\"\\t\\t}\"},{\"line\":51,\"text\":\"\"},{\"line\":52,\"text\":\"\\t\\t$setup = $addOn->getSetup();\"},{\"line\":53,\"text\":\"\"},{\"line\":54,\"text\":\"\\t\\tif (!$setup)\"},{\"line\":55,\"text\":\"\\t\\t{\"},{\"line\":56,\"text\":\"\\t\\t\\t$output->writeln(\\\"Setup class for add-on could not be found.\\\");\"},{\"line\":57,\"text\":\"\\t\\t\\treturn 1;\"},{\"line\":58,\"text\":\"\\t\\t}\"},{\"line\":59,\"text\":\"\"},{\"line\":60,\"text\":\"\\t\\t$step = $input->getArgument('step');\"},{\"line\":61,\"text\":\"\\t\\t$version = null;\"},{\"line\":62,\"text\":\"\\t\\t$params = [];\"},{\"line\":63,\"text\":\"\"},{\"line\":64,\"text\":\"\\t\\t$stepType = $this->getStepType();\"},{\"line\":65,\"text\":\"\\t\\tif ($stepType == 'upgrade')\"},{\"line\":66,\"text\":\"\\t\\t{\"},{\"line\":67,\"text\":\"\\t\\t\\t$version = $input->getArgument('version');\"},{\"line\":68,\"text\":\"\\t\\t}\"},{\"line\":69,\"text\":\"\"},{\"line\":70,\"text\":\"\\t\\t$setup->prepareForAction($stepType);\"},{\"line\":71,\"text\":\"\"},{\"line\":72,\"text\":\"\\t\\tdo\"},{\"line\":73,\"text\":\"\\t\\t{\"},{\"line\":74,\"text\":\"\\t\\t\\t$result = $this->runStep($setup, $output, $stepType, $step, $version, $params);\"},{\"line\":75,\"text\":\"\\t\\t\\tif (!($result instanceof StepResult))\"},{\"line\":76,\"text\":\"\\t\\t\\t{\"},{\"line\":77,\"text\":\"\\t\\t\\t\\t$this->clearStatus($output, \\\"Must return a StepResult object.\\\");\"},{\"line\":78,\"text\":\"\\t\\t\\t\\treturn 1;\"},{\"line\":79,\"text\":\"\\t\\t\\t}\"},{\"line\":80,\"text\":\"\\t\\t\\telse\"},{\"line\":81,\"text\":\"\\t\\t\\t{\"},{\"line\":82,\"text\":\"\\t\\t\\t\\tif ($result->complete)\"},{\"line\":83,\"text\":\"\\t\\t\\t\\t{\"},{\"line\":84,\"text\":\"\\t\\t\\t\\t\\t$loop = false;\"},{\"line\":85,\"text\":\"\\t\\t\\t\\t}\"},{\"line\":86,\"text\":\"\\t\\t\\t\\telse if (is_int($result))\"},{\"line\":87,\"text\":\"\\t\\t\\t\\t{\"},{\"line\":88,\"text\":\"\\t\\t\\t\\t\\t$loop = false;\"},{\"line\":89,\"text\":\"\\t\\t\\t\\t}\"},{\"line\":90,\"text\":\"\\t\\t\\t\\telse\"},{\"line\":91,\"text\":\"\\t\\t\\t\\t{\"},{\"line\":92,\"text\":\"\\t\\t\\t\\t\\t$params = $result->params;\"},{\"line\":93,\"text\":\"\\t\\t\\t\\t\\t$loop = true;\"},{\"line\":104,\"text\":\"\\tprotected function runStep(AbstractSetup $setup, OutputInterface $output, $stepType, $step, $version = null, array $params = [])\"},{\"line\":105,\"text\":\"\\t{\"},{\"line\":106,\"text\":\"\\t\\t$method = $stepType;\"},{\"line\":107,\"text\":\"\"},{\"line\":108,\"text\":\"\\t\\tswitch ($method)\"},{\"line\":109,\"text\":\"\\t\\t{\"},{\"line\":110,\"text\":\"\\t\\t\\tcase 'install':\"},{\"line\":111,\"text\":\"\\t\\t\\tcase 'uninstall':\"},{\"line\":112,\"text\":\"\\t\\t\\t\\tif ($step)\"},{\"line\":113,\"text\":\"\\t\\t\\t\\t{\"},{\"line\":114,\"text\":\"\\t\\t\\t\\t\\t$method .= 'Step' . $step;\"},{\"line\":115,\"text\":\"\\t\\t\\t\\t}\"},{\"line\":116,\"text\":\"\\t\\t\\t\\tbreak;\"},{\"line\":117,\"text\":\"\"},{\"line\":118,\"text\":\"\\t\\t\\tcase 'upgrade':\"},{\"line\":119,\"text\":\"\\t\\t\\t\\tif ($version && $step)\"},{\"line\":120,\"text\":\"\\t\\t\\t\\t{\"},{\"line\":121,\"text\":\"\\t\\t\\t\\t\\t$method .= $version . 'Step' . $step;\"},{\"line\":122,\"text\":\"\\t\\t\\t\\t}\"},{\"line\":123,\"text\":\"\\t\\t\\t\\tbreak;\"},{\"line\":124,\"text\":\"\\t\\t}\"},{\"line\":125,\"text\":\"\"},{\"line\":126,\"text\":\"\\t\\tif (!method_exists($setup, $method))\"}],\"sha256\":\"86ac6e9eda2202a75f3566a6bf20b14b5cc5171a823e0a23de0e66d0e8c0a8b7\"},{\"file\":\"src/XF/Cli/Command/AddOn/Create.php\",\"matches\":[{\"line\":40,\"text\":\"\\t\\tif ($devOutput->isAddOnSkipped($addOnId))\"},{\"line\":41,\"text\":\"\\t\\t{\"},{\"line\":42,\"text\":\"\\t\\t\\t$output->writeln(\\\"Development output for this add-on ID has been disabled. Cannot continue.\\\");\"},{\"line\":43,\"text\":\"\\t\\t\\tif (strtolower(substr($addOnId, 0, 2)) == 'xf')\"},{\"line\":44,\"text\":\"\\t\\t\\t{\"},{\"line\":45,\"text\":\"\\t\\t\\t\\t$output->writeln(\\\"Note: use of add-on IDs starting with 'xf' is strongly discouraged.\\\");\"},{\"line\":46,\"text\":\"\\t\\t\\t}\"},{\"line\":47,\"text\":\"\\t\\t\\treturn 1;\"},{\"line\":48,\"text\":\"\\t\\t}\"},{\"line\":49,\"text\":\"\"},{\"line\":50,\"text\":\"\\t\\t$checkPath = \\\\XF::getAddOnDirectory();\"},{\"line\":51,\"text\":\"\"},{\"line\":52,\"text\":\"\\t\\t$addOnManager = \\\\XF::app()->addOnManager();\"},{\"line\":53,\"text\":\"\\t\\tforeach ($addOnManager->getAllAddOns() AS $existingAddOnId => $existingAddOn)\"},{\"line\":54,\"text\":\"\\t\\t{\"},{\"line\":55,\"text\":\"\\t\\t\\tif ($existingAddOnId !== $addOnId && strcasecmp($existingAddOnId, $addOnId) === 0)\"},{\"line\":56,\"text\":\"\\t\\t\\t{\"},{\"line\":57,\"text\":\"\\t\\t\\t\\t$output->writeln(\\\"Add-on ID '{$addOnId}' conflicts with existing add-on '{$existingAddOnId}' (case mismatch).\\\");\"},{\"line\":58,\"text\":\"\\t\\t\\t\\treturn 1;\"},{\"line\":59,\"text\":\"\\t\\t\\t}\"},{\"line\":60,\"text\":\"\\t\\t}\"},{\"line\":61,\"text\":\"\"},{\"line\":62,\"text\":\"\\t\\tif (strpos($addOnId, '/') !== false)\"},{\"line\":63,\"text\":\"\\t\\t{\"},{\"line\":64,\"text\":\"\\t\\t\\t$addOnIdParts = explode('/', $addOnId);\"},{\"line\":65,\"text\":\"\\t\\t\\t$vendor = reset($addOnIdParts);\"},{\"line\":66,\"text\":\"\"},{\"line\":67,\"text\":\"\\t\\t\\tif (file_exists(\\\\XF::getAddOnDirectory() . \\\\XF::$DS . $vendor))\"},{\"line\":68,\"text\":\"\\t\\t\\t{\"},{\"line\":69,\"text\":\"\\t\\t\\t\\t$checkPath = \\\\XF::getAddOnDirectory() . \\\\XF::$DS . $vendor;\"},{\"line\":70,\"text\":\"\\t\\t\\t}\"},{\"line\":71,\"text\":\"\"},{\"line\":72,\"text\":\"\\t\\t\\tif ($addOnDir = opendir(\\\\XF::getAddOnDirectory()))\"},{\"line\":73,\"text\":\"\\t\\t\\t{\"},{\"line\":74,\"text\":\"\\t\\t\\t\\twhile (($dir = readdir($addOnDir)) !== false)\"},{\"line\":75,\"text\":\"\\t\\t\\t\\t{\"},{\"line\":76,\"text\":\"\\t\\t\\t\\t\\tif (strcasecmp($dir, $vendor) == 0 && $dir != $vendor)\"},{\"line\":77,\"text\":\"\\t\\t\\t\\t\\t{\"},{\"line\":78,\"text\":\"\\t\\t\\t\\t\\t\\t$output->writeln(\\\"The '{$checkPath}' directory conflicts with an existing directory with the same name but a different case.\\\");\"},{\"line\":79,\"text\":\"\\t\\t\\t\\t\\t\\treturn 1;\"},{\"line\":80,\"text\":\"\\t\\t\\t\\t\\t}\"},{\"line\":81,\"text\":\"\\t\\t\\t\\t}\"},{\"line\":82,\"text\":\"\\t\\t\\t\\tclosedir($addOnDir);\"},{\"line\":83,\"text\":\"\\t\\t\\t}\"},{\"line\":84,\"text\":\"\\t\\t}\"},{\"line\":85,\"text\":\"\"},{\"line\":86,\"text\":\"\\t\\tif (!is_writable($checkPath))\"},{\"line\":87,\"text\":\"\\t\\t{\"},{\"line\":88,\"text\":\"\\t\\t\\t$checkPathPrintable = str_replace(\\\\XF::getRootDirectory() . \\\\XF::$DS, '', $checkPath);\"},{\"line\":89,\"text\":\"\\t\\t\\t$output->writeln(\\\"The '{$checkPathPrintable}' directory is not writable.\\\");\"},{\"line\":90,\"text\":\"\\t\\t\\treturn 1;\"},{\"line\":91,\"text\":\"\\t\\t}\"},{\"line\":92,\"text\":\"\"},{\"line\":93,\"text\":\"\\t\\t$addOnObj = new AddOn($addOnId, \\\\XF::app()->addOnManager());\"},{\"line\":94,\"text\":\"\"},{\"line\":95,\"text\":\"\\t\\t$jsonPath = $addOnObj->getJsonPath();\"},{\"line\":96,\"text\":\"\"},{\"line\":97,\"text\":\"\\t\\tif (file_exists($jsonPath))\"},{\"line\":98,\"text\":\"\\t\\t{\"},{\"line\":99,\"text\":\"\\t\\t\\t$output->writeln(\\\"The addon.json file already exists at {$jsonPath}. You can create the add-on by installing it from the Admin CP.\\\");\"},{\"line\":100,\"text\":\"\\t\\t\\treturn 1;\"},{\"line\":101,\"text\":\"\\t\\t}\"},{\"line\":102,\"text\":\"\"},{\"line\":103,\"text\":\"\\t\\t$question = new Question(\\\"Enter a title: \\\");\"},{\"line\":104,\"text\":\"\\t\\t$question->setValidator($this->getAddOnQuestionFieldValidator('title'));\"},{\"line\":105,\"text\":\"\\t\\t$title = $helper->ask($input, $output, $question);\"},{\"line\":106,\"text\":\"\\t\\t$output->writeln(\\\"\\\");\"},{\"line\":107,\"text\":\"\"},{\"line\":108,\"text\":\"\\t\\t$question = new Question(\\\"Enter a version ID. This integer will be used for internal version comparisons. Each release of your add-on should increase this number: \\\");\"},{\"line\":109,\"text\":\"\\t\\t$question->setValidator(function ($value)\"},{\"line\":110,\"text\":\"\\t\\t{\"},{\"line\":111,\"text\":\"\\t\\t\\tif (!preg_match('/^[0-9]+$/', $value))\"},{\"line\":112,\"text\":\"\\t\\t\\t{\"},{\"line\":113,\"text\":\"\\t\\t\\t\\tthrow new \\\\InvalidArgumentException(\\\"The version ID should contain numeric values only.\\\");\"},{\"line\":114,\"text\":\"\\t\\t\\t}\"},{\"line\":115,\"text\":\"\\t\\t\\treturn $value;\"},{\"line\":170,\"text\":\"\"},{\"line\":171,\"text\":\"\\t\\t$output->writeln(\\\"\\\");\"},{\"line\":172,\"text\":\"\"},{\"line\":173,\"text\":\"\\t\\t$addOn->preSave();\"},{\"line\":174,\"text\":\"\\t\\tif ($errors = $addOn->getErrors())\"},{\"line\":175,\"text\":\"\\t\\t{\"},{\"line\":176,\"text\":\"\\t\\t\\t$output->writeln(\\\"An unexpected error occurred while saving the add-on: \\\" . reset($errors) . \\\"\\\");\"},{\"line\":177,\"text\":\"\\t\\t\\treturn 1;\"},{\"line\":178,\"text\":\"\\t\\t}\"},{\"line\":179,\"text\":\"\"},{\"line\":180,\"text\":\"\\t\\t$addOn->save();\"},{\"line\":181,\"text\":\"\"},{\"line\":182,\"text\":\"\\t\\tFile::createDirectory($addOnObj->getAddOnDirectory(), false);\"},{\"line\":183,\"text\":\"\"},{\"line\":184,\"text\":\"\\t\\t$json = [\"},{\"line\":185,\"text\":\"\\t\\t\\t'title' => $addOn->title,\"},{\"line\":186,\"text\":\"\\t\\t\\t'version_string' => $addOn->version_string,\"},{\"line\":187,\"text\":\"\\t\\t\\t'version_id' => intval($addOn->version_id),\"},{\"line\":188,\"text\":\"\\t\\t];\"},{\"line\":189,\"text\":\"\\t\\tif ($legacyAddOnId)\"},{\"line\":190,\"text\":\"\\t\\t{\"},{\"line\":191,\"text\":\"\\t\\t\\t$json['legacy_addon_id'] = $legacyAddOnId;\"},{\"line\":192,\"text\":\"\\t\\t}\"},{\"line\":220,\"text\":\"\\t\\t\\t\\t$setupContent = <<< SETUP\"}],\"sha256\":\"4ff8f77caa12327158b9a6ba6ed2ffe85b959011279be5a70a8b3e77f75204f5\"},{\"file\":\"src/XF/Cli/Command/AddOn/UninstallStep.php\",\"matches\":[{\"line\":1,\"text\":\"addArgument(\"},{\"line\":17,\"text\":\"\\t\\t\\t'step',\"},{\"line\":18,\"text\":\"\\t\\t\\tInputArgument::REQUIRED,\"},{\"line\":19,\"text\":\"\\t\\t\\t'The step number to run.'\"},{\"line\":20,\"text\":\"\\t\\t);\"},{\"line\":21,\"text\":\"\\t}\"},{\"line\":22,\"text\":\"}\"}],\"sha256\":\"d69b287acd3ea5c02bf23492e1bdef465fb75f22f00b45acdb4ffafe547260e5\"},{\"file\":\"src/XF/AddOn/AbstractSetup.php\",\"matches\":[{\"line\":32,\"text\":\"\\tabstract public function upgrade(array $stepParams = []);\"},{\"line\":33,\"text\":\"\"},{\"line\":34,\"text\":\"\\t/**\"},{\"line\":35,\"text\":\"\\t * @param array $stepParams\"},{\"line\":36,\"text\":\"\\t *\"},{\"line\":37,\"text\":\"\\t * @return null|StepResult\"},{\"line\":38,\"text\":\"\\t */\"},{\"line\":39,\"text\":\"\\tabstract public function uninstall(array $stepParams = []);\"},{\"line\":40,\"text\":\"\"},{\"line\":41,\"text\":\"\\tpublic function __construct(AddOn $addOn, App $app)\"},{\"line\":42,\"text\":\"\\t{\"},{\"line\":43,\"text\":\"\\t\\t$this->addOn = $addOn;\"},{\"line\":44,\"text\":\"\\t\\t$this->app = $app;\"},{\"line\":45,\"text\":\"\\t}\"},{\"line\":46,\"text\":\"\"},{\"line\":47,\"text\":\"\\t/**\"},{\"line\":48,\"text\":\"\\t * Perform additional requirement checks.\"},{\"line\":49,\"text\":\"\\t *\"},{\"line\":50,\"text\":\"\\t * @param list $errors Errors will block the setup from continuing\"},{\"line\":51,\"text\":\"\\t * @param list $warnings Warnings will be displayed but allow the user to continue setup\"},{\"line\":52,\"text\":\"\\t *\"},{\"line\":53,\"text\":\"\\t * @return void\"},{\"line\":54,\"text\":\"\\t */\"},{\"line\":86,\"text\":\"\\t\\t$this->app->jobManager()->enqueueUnique($uniqueId, FileCleanUp::class, [\"},{\"line\":87,\"text\":\"\\t\\t\\t'addon_id' => $addOn->addon_id,\"},{\"line\":88,\"text\":\"\\t\\t], false);\"},{\"line\":89,\"text\":\"\\t}\"},{\"line\":90,\"text\":\"\"},{\"line\":91,\"text\":\"\\tpublic function prepareForAction($action)\"},{\"line\":92,\"text\":\"\\t{\"},{\"line\":93,\"text\":\"\\t\\tif ($action == 'uninstall')\"},{\"line\":94,\"text\":\"\\t\\t{\"},{\"line\":95,\"text\":\"\\t\\t\\t\\\\XF::db()->ignoreLegacyTableWriteError(true);\"},{\"line\":96,\"text\":\"\\t\\t}\"},{\"line\":97,\"text\":\"\\t}\"},{\"line\":98,\"text\":\"\"},{\"line\":99,\"text\":\"\\t/**\"},{\"line\":100,\"text\":\"\\t * @param $sql\"},{\"line\":101,\"text\":\"\\t * @param array $bind\"},{\"line\":102,\"text\":\"\\t * @param bool $suppressAll\"},{\"line\":103,\"text\":\"\\t *\"},{\"line\":104,\"text\":\"\\t * @return bool|AbstractStatement\"},{\"line\":105,\"text\":\"\\t * @throws Exception\"},{\"line\":106,\"text\":\"\\t */\"},{\"line\":107,\"text\":\"\\tprotected function query($sql, $bind = [], $suppressAll = false)\"},{\"line\":108,\"text\":\"\\t{\"}],\"sha256\":\"6bdd3fe834e15b963a52c9357f54262f2d12f3c7c3686fc31333b549cddf2d88\"},{\"file\":\"src/XF/AddOn/AddOn.php\",\"matches\":[{\"line\":332,\"text\":\"\\t\\t\\t\\t}\"},{\"line\":333,\"text\":\"\\t\\t\\t}\"},{\"line\":334,\"text\":\"\\t\\t}\"},{\"line\":335,\"text\":\"\"},{\"line\":336,\"text\":\"\\t\\treturn $this->setup;\"},{\"line\":337,\"text\":\"\\t}\"},{\"line\":338,\"text\":\"\"},{\"line\":339,\"text\":\"\\tpublic function isInstalled()\"},{\"line\":340,\"text\":\"\\t{\"},{\"line\":341,\"text\":\"\\t\\tif ($this->installedAddOn === null)\"},{\"line\":342,\"text\":\"\\t\\t{\"},{\"line\":343,\"text\":\"\\t\\t\\treturn false;\"},{\"line\":344,\"text\":\"\\t\\t}\"},{\"line\":345,\"text\":\"\"},{\"line\":346,\"text\":\"\\t\\t$lastAction = $this->installedAddOn->getLastActionStep('install');\"},{\"line\":347,\"text\":\"\\t\\tif ($lastAction !== null)\"},{\"line\":348,\"text\":\"\\t\\t{\"},{\"line\":349,\"text\":\"\\t\\t\\t// we haven't completed the install steps yet, don't consider as installed\"},{\"line\":350,\"text\":\"\\t\\t\\treturn false;\"},{\"line\":351,\"text\":\"\\t\\t}\"},{\"line\":352,\"text\":\"\"},{\"line\":353,\"text\":\"\\t\\treturn true;\"},{\"line\":354,\"text\":\"\\t}\"},{\"line\":355,\"text\":\"\"},{\"line\":356,\"text\":\"\\tpublic function isActive()\"},{\"line\":357,\"text\":\"\\t{\"},{\"line\":358,\"text\":\"\\t\\treturn $this->isInstalled()\"},{\"line\":359,\"text\":\"\\t\\t\\t&& $this->installedAddOn->active;\"},{\"line\":360,\"text\":\"\\t}\"},{\"line\":361,\"text\":\"\"},{\"line\":362,\"text\":\"\\tpublic function isLegacy()\"},{\"line\":363,\"text\":\"\\t{\"},{\"line\":364,\"text\":\"\\t\\treturn $this->isInstalled()\"},{\"line\":365,\"text\":\"\\t\\t\\t&& $this->installedAddOn->is_legacy;\"},{\"line\":366,\"text\":\"\\t}\"},{\"line\":367,\"text\":\"\"},{\"line\":368,\"text\":\"\\tpublic function isDevOutputAvailable()\"},{\"line\":369,\"text\":\"\\t{\"},{\"line\":370,\"text\":\"\\t\\treturn \\\\XF::app()->developmentOutput()->isAddOnOutputAvailable($this->getAddOnId());\"},{\"line\":371,\"text\":\"\\t}\"},{\"line\":372,\"text\":\"\"},{\"line\":373,\"text\":\"\\tpublic function hasMissingFiles()\"},{\"line\":374,\"text\":\"\\t{\"},{\"line\":375,\"text\":\"\\t\\treturn count($this->missingFiles) > 0;\"},{\"line\":376,\"text\":\"\\t}\"},{\"line\":377,\"text\":\"\"},{\"line\":378,\"text\":\"\\tpublic function hasPendingChanges()\"},{\"line\":379,\"text\":\"\\t{\"},{\"line\":380,\"text\":\"\\t\\treturn $this->isInstalled()\"},{\"line\":381,\"text\":\"\\t\\t\\t&& !$this->isLegacy()\"},{\"line\":382,\"text\":\"\\t\\t\\t&& (\"},{\"line\":383,\"text\":\"\\t\\t\\t\\t!$this->isFileVersionValid()\"},{\"line\":384,\"text\":\"\\t\\t\\t\\t|| $this->isJsonHashChanged()\"},{\"line\":385,\"text\":\"\\t\\t\\t);\"},{\"line\":386,\"text\":\"\\t}\"},{\"line\":387,\"text\":\"\"},{\"line\":388,\"text\":\"\\tpublic function hasFaIcon()\"},{\"line\":389,\"text\":\"\\t{\"},{\"line\":390,\"text\":\"\\t\\treturn (\"},{\"line\":391,\"text\":\"\\t\\t\\t$this->icon\"},{\"line\":392,\"text\":\"\\t\\t\\t&& !$this->hasIcon()\"},{\"line\":393,\"text\":\"\\t\\t\\t&& preg_match('#^(fa-|fa[a-z] )#', $this->icon)\"},{\"line\":394,\"text\":\"\\t\\t);\"},{\"line\":395,\"text\":\"\\t}\"},{\"line\":431,\"text\":\"\\tpublic function isAvailable()\"},{\"line\":432,\"text\":\"\\t{\"},{\"line\":433,\"text\":\"\\t\\treturn count($this->missingFiles) == 0;\"},{\"line\":434,\"text\":\"\\t}\"},{\"line\":435,\"text\":\"\"},{\"line\":436,\"text\":\"\\tpublic function isFileVersionValid()\"},{\"line\":437,\"text\":\"\\t{\"},{\"line\":438,\"text\":\"\\t\\treturn $this->isInstalled()\"},{\"line\":439,\"text\":\"\\t\\t\\t&& $this->isAvailable()\"},{\"line\":440,\"text\":\"\\t\\t\\t&& $this->installedAddOn->version_id == $this->json['version_id'];\"},{\"line\":441,\"text\":\"\\t}\"},{\"line\":442,\"text\":\"\"},{\"line\":443,\"text\":\"\\tpublic function isJsonHashChanged()\"},{\"line\":444,\"text\":\"\\t{\"},{\"line\":445,\"text\":\"\\t\\treturn (\"},{\"line\":446,\"text\":\"\\t\\t\\t$this->isAvailable()\"},{\"line\":447,\"text\":\"\\t\\t\\t&& $this->getJsonHash() !== $this->installedAddOn->json_hash\"},{\"line\":448,\"text\":\"\\t\\t);\"},{\"line\":449,\"text\":\"\\t}\"},{\"line\":450,\"text\":\"\"},{\"line\":451,\"text\":\"\\tpublic function isJsonVersionNewer()\"},{\"line\":452,\"text\":\"\\t{\"},{\"line\":453,\"text\":\"\\t\\treturn ($this->json['version_id'] > $this->installedAddOn->version_id);\"},{\"line\":459,\"text\":\"\\t\\t\\t'version_id' => $this->json['version_id'],\"},{\"line\":460,\"text\":\"\\t\\t\\t'version_string' => $this->json['version_string'],\"},{\"line\":461,\"text\":\"\\t\\t];\"},{\"line\":462,\"text\":\"\\t}\"},{\"line\":463,\"text\":\"\"},{\"line\":464,\"text\":\"\\tpublic function canUpgrade()\"},{\"line\":465,\"text\":\"\\t{\"},{\"line\":466,\"text\":\"\\t\\treturn $this->isInstalled()\"},{\"line\":467,\"text\":\"\\t\\t\\t&& $this->isJsonHashChanged()\"},{\"line\":468,\"text\":\"\\t\\t\\t&& $this->isJsonVersionNewer()\"},{\"line\":469,\"text\":\"\\t\\t\\t&& $this->canEdit();\"},{\"line\":470,\"text\":\"\\t}\"},{\"line\":471,\"text\":\"\"}],\"sha256\":\"0e0346a046fff6bde9850cb53e9dc0d0b5379387029dc16925e562fa141ab422\"},{\"file\":\"src/XF/AddOn/DataManager.php\",\"matches\":[{\"line\":28,\"text\":\"use XF\\\\AddOn\\\\DataType\\\\StylePropertyGroup;\"},{\"line\":29,\"text\":\"use XF\\\\AddOn\\\\DataType\\\\Template;\"},{\"line\":30,\"text\":\"use XF\\\\AddOn\\\\DataType\\\\TemplateModification;\"},{\"line\":31,\"text\":\"use XF\\\\AddOn\\\\DataType\\\\WidgetDefinition;\"},{\"line\":32,\"text\":\"use XF\\\\AddOn\\\\DataType\\\\WidgetPosition;\"},{\"line\":33,\"text\":\"use XF\\\\Finder\\\\AddOnFinder;\"},{\"line\":34,\"text\":\"use XF\\\\Job\\\\AddOnData;\"},{\"line\":35,\"text\":\"use XF\\\\Job\\\\AddOnUninstallData;\"},{\"line\":36,\"text\":\"use XF\\\\Job\\\\Atomic;\"},{\"line\":37,\"text\":\"use XF\\\\Mvc\\\\Entity\\\\Manager;\"},{\"line\":38,\"text\":\"use XF\\\\Repository\\\\ClassExtensionRepository;\"},{\"line\":39,\"text\":\"use XF\\\\Repository\\\\CodeEventListenerRepository;\"},{\"line\":40,\"text\":\"use XF\\\\Repository\\\\ForumTypeRepository;\"},{\"line\":41,\"text\":\"use XF\\\\Repository\\\\PaymentRepository;\"},{\"line\":42,\"text\":\"use XF\\\\Repository\\\\RouteRepository;\"},{\"line\":43,\"text\":\"use XF\\\\Repository\\\\ThreadTypeRepository;\"},{\"line\":44,\"text\":\"use XF\\\\Util\\\\File;\"},{\"line\":45,\"text\":\"\"},{\"line\":46,\"text\":\"class DataManager\"},{\"line\":47,\"text\":\"{\"},{\"line\":48,\"text\":\"\\t/**\"},{\"line\":49,\"text\":\"\\t * @var Manager\"},{\"line\":50,\"text\":\"\\t */\"},{\"line\":132,\"text\":\"\\t\\t$addOnManager = \\\\XF::app()->addOnManager();\"},{\"line\":133,\"text\":\"\"},{\"line\":134,\"text\":\"\\t\\t$addOns = $this->em->getFinder(AddOnFinder::class)->where('active', 1)->fetch();\"},{\"line\":135,\"text\":\"\\t\\tforeach ($addOns AS $addOn)\"},{\"line\":136,\"text\":\"\\t\\t{\"},{\"line\":137,\"text\":\"\\t\\t\\t$activeAddOns[$addOn->addon_id] = $addOn->version_id;\"},{\"line\":138,\"text\":\"\"},{\"line\":139,\"text\":\"\\t\\t\\t$addOnClass = $addOnManager->getById($addOn->addon_id);\"},{\"line\":140,\"text\":\"\\t\\t\\tif ($addOnClass)\"},{\"line\":141,\"text\":\"\\t\\t\\t{\"},{\"line\":142,\"text\":\"\\t\\t\\t\\t$addOnId = $addOn->addon_id;\"},{\"line\":143,\"text\":\"\\t\\t\\t\\t$autoloadPath = $addOnClass->composer_autoload;\"},{\"line\":144,\"text\":\"\"},{\"line\":145,\"text\":\"\\t\\t\\t\\tif (!$autoloadPath)\"},{\"line\":146,\"text\":\"\\t\\t\\t\\t{\"},{\"line\":147,\"text\":\"\\t\\t\\t\\t\\tcontinue;\"},{\"line\":148,\"text\":\"\\t\\t\\t\\t}\"},{\"line\":149,\"text\":\"\"},{\"line\":150,\"text\":\"\\t\\t\\t\\t$addOnAutoload = $addOnManager->getAddOnPath($addOnId) . \\\\XF::$DS . $autoloadPath;\"},{\"line\":151,\"text\":\"\"},{\"line\":152,\"text\":\"\\t\\t\\t\\tif (!$this->checkComposerAutoloadPath('installed.json', $addOnAutoload))\"},{\"line\":153,\"text\":\"\\t\\t\\t\\t{\"},{\"line\":154,\"text\":\"\\t\\t\\t\\t\\tcontinue;\"},{\"line\":266,\"text\":\"\\t\\t}\"},{\"line\":267,\"text\":\"\"},{\"line\":268,\"text\":\"\\t\\t$db->commit();\"},{\"line\":269,\"text\":\"\\t}\"},{\"line\":270,\"text\":\"\"},{\"line\":271,\"text\":\"\\tpublic function enqueueRemoveAddOnData($id)\"},{\"line\":272,\"text\":\"\\t{\"},{\"line\":273,\"text\":\"\\t\\treturn \\\\XF::app()->jobManager()->enqueueUnique($id . 'AddOnUnInstall', AddOnUninstallData::class, [\"},{\"line\":274,\"text\":\"\\t\\t\\t'addon_id' => $id,\"},{\"line\":275,\"text\":\"\\t\\t]);\"},{\"line\":276,\"text\":\"\\t}\"},{\"line\":277,\"text\":\"\"},{\"line\":278,\"text\":\"\\tpublic function finalizeRemoveAddOnData($addOnId)\"},{\"line\":279,\"text\":\"\\t{\"},{\"line\":280,\"text\":\"\\t\\t$simpleCache = \\\\XF::app()->simpleCache();\"},{\"line\":281,\"text\":\"\\t\\t$simpleCache->deleteSet($addOnId);\"},{\"line\":282,\"text\":\"\"},{\"line\":283,\"text\":\"\\t\\t$this->rebuildActiveAddOnCache();\"},{\"line\":284,\"text\":\"\\t}\"},{\"line\":285,\"text\":\"\"},{\"line\":286,\"text\":\"\\t/**\"},{\"line\":287,\"text\":\"\\t * @template T of AbstractDataType\"},{\"line\":288,\"text\":\"\\t *\"}],\"sha256\":\"cfc97d6e825ba983234c86a405bbcf985706575bba6325e253a70c05001338f0\"},{\"file\":\"src/XF/AddOn/StepRunnerUninstallTrait.php\",\"matches\":[{\"line\":3,\"text\":\"namespace XF\\\\AddOn;\"},{\"line\":4,\"text\":\"\"},{\"line\":5,\"text\":\"use function is_array;\"},{\"line\":6,\"text\":\"\"},{\"line\":7,\"text\":\"/**\"},{\"line\":8,\"text\":\" * @property AddOn $addOn\"},{\"line\":9,\"text\":\" */\"},{\"line\":10,\"text\":\"trait StepRunnerUninstallTrait\"},{\"line\":11,\"text\":\"{\"},{\"line\":12,\"text\":\"\\t/**\"},{\"line\":13,\"text\":\"\\t * @param array $stepParams\"},{\"line\":14,\"text\":\"\\t *\"},{\"line\":15,\"text\":\"\\t * @return null|StepResult\"},{\"line\":16,\"text\":\"\\t */\"},{\"line\":17,\"text\":\"\\tpublic function uninstall(array $stepParams = [])\"},{\"line\":18,\"text\":\"\\t{\"},{\"line\":19,\"text\":\"\\t\\t$stepParams = array_replace([\"},{\"line\":20,\"text\":\"\\t\\t\\t'step' => 0,\"},{\"line\":21,\"text\":\"\\t\\t], $stepParams);\"},{\"line\":22,\"text\":\"\"},{\"line\":23,\"text\":\"\\t\\t$step = $stepParams['step'];\"},{\"line\":24,\"text\":\"\\t\\tif (!$step)\"},{\"line\":25,\"text\":\"\\t\\t{\"},{\"line\":26,\"text\":\"\\t\\t\\t$step = $this->getUninstallResumeStep();\"},{\"line\":27,\"text\":\"\\t\\t}\"},{\"line\":28,\"text\":\"\\t\\treturn $this->uninstallStepRunner($step, $stepParams);\"},{\"line\":29,\"text\":\"\\t}\"},{\"line\":30,\"text\":\"\"},{\"line\":31,\"text\":\"\\tprivate function getUninstallResumeStep()\"},{\"line\":32,\"text\":\"\\t{\"},{\"line\":33,\"text\":\"\\t\\t$installedAddOn = $this->addOn->getInstalledAddOn();\"},{\"line\":34,\"text\":\"\\t\\tif ($installedAddOn)\"},{\"line\":35,\"text\":\"\\t\\t{\"},{\"line\":36,\"text\":\"\\t\\t\\t$lastActionStep = $installedAddOn->getLastActionStep('uninstall');\"},{\"line\":37,\"text\":\"\\t\\t\\tif ($lastActionStep)\"},{\"line\":38,\"text\":\"\\t\\t\\t{\"},{\"line\":39,\"text\":\"\\t\\t\\t\\treturn $lastActionStep + 1; // this is the last completed step, so resume with the next\"},{\"line\":40,\"text\":\"\\t\\t\\t}\"},{\"line\":41,\"text\":\"\\t\\t}\"},{\"line\":42,\"text\":\"\"},{\"line\":43,\"text\":\"\\t\\treturn 1;\"},{\"line\":44,\"text\":\"\\t}\"},{\"line\":45,\"text\":\"\"},{\"line\":46,\"text\":\"\\t/**\"},{\"line\":47,\"text\":\"\\t * @param integer $step\"},{\"line\":48,\"text\":\"\\t * @param array $stepParams\"},{\"line\":49,\"text\":\"\\t *\"},{\"line\":50,\"text\":\"\\t * @return null|StepResult\"},{\"line\":51,\"text\":\"\\t */\"},{\"line\":52,\"text\":\"\\tprivate function uninstallStepRunner($step, array $stepParams)\"},{\"line\":53,\"text\":\"\\t{\"},{\"line\":54,\"text\":\"\\t\\t$fnPrefix = 'uninstallStep';\"},{\"line\":55,\"text\":\"\\t\\t$fn = $fnPrefix . $step;\"},{\"line\":56,\"text\":\"\\t\\tif (!method_exists($this, $fn))\"},{\"line\":57,\"text\":\"\\t\\t{\"},{\"line\":58,\"text\":\"\\t\\t\\treturn null;\"},{\"line\":59,\"text\":\"\\t\\t}\"},{\"line\":60,\"text\":\"\"},{\"line\":61,\"text\":\"\\t\\t$result = $this->$fn($stepParams);\"},{\"line\":62,\"text\":\"\\t\\tif ($result === null || $result === true)\"},{\"line\":63,\"text\":\"\\t\\t{\"},{\"line\":64,\"text\":\"\\t\\t\\t$result = new StepResult(true);\"},{\"line\":65,\"text\":\"\\t\\t}\"},{\"line\":66,\"text\":\"\\t\\telse if (is_array($result))\"},{\"line\":67,\"text\":\"\\t\\t{\"},{\"line\":68,\"text\":\"\\t\\t\\t$result = new StepResult(false, $result);\"},{\"line\":69,\"text\":\"\\t\\t}\"},{\"line\":73,\"text\":\"\\t\\t\\tthrow new \\\\LogicException(\\\"Must return a StepResult object\\\");\"},{\"line\":74,\"text\":\"\\t\\t}\"},{\"line\":75,\"text\":\"\"},{\"line\":76,\"text\":\"\\t\\t$result->step = $step;\"},{\"line\":77,\"text\":\"\"},{\"line\":78,\"text\":\"\\t\\tif ($result->complete)\"},{\"line\":79,\"text\":\"\\t\\t{\"},{\"line\":80,\"text\":\"\\t\\t\\t$this->addOn->updatePendingAction('uninstall', $result->step);\"},{\"line\":81,\"text\":\"\"},{\"line\":82,\"text\":\"\\t\\t\\t$nextStep = $step + 1;\"},{\"line\":83,\"text\":\"\\t\\t\\t$nextFn = $fnPrefix . $nextStep;\"},{\"line\":84,\"text\":\"\\t\\t\\tif (!method_exists($this, $nextFn))\"},{\"line\":85,\"text\":\"\\t\\t\\t{\"},{\"line\":86,\"text\":\"\\t\\t\\t\\treturn null;\"},{\"line\":87,\"text\":\"\\t\\t\\t}\"},{\"line\":88,\"text\":\"\"},{\"line\":89,\"text\":\"\\t\\t\\t$result = new StepResult(false, [], $nextStep);\"},{\"line\":90,\"text\":\"\\t\\t}\"},{\"line\":91,\"text\":\"\"},{\"line\":92,\"text\":\"\\t\\treturn $result;\"},{\"line\":93,\"text\":\"\\t}\"},{\"line\":94,\"text\":\"}\"}],\"sha256\":\"e58a9ab9c30e3cf3c41a0be392e8c5ac37f744578f7b91f76d663139649c49a9\"}],\"state\":{\"addon_columns\":[\"addon_id\",\"title\",\"version_string\",\"version_id\",\"json_hash\",\"active\",\"is_legacy\",\"is_processing\",\"last_pending_action\"],\"addon_object\":{\"canUninstall\":{\"exists\":true,\"public\":true,\"required\":0,\"total\":0,\"value\":false},\"class\":\"XF\\\\AddOn\\\\AddOn\",\"getAddOnId\":{\"exists\":true,\"public\":true,\"required\":0,\"total\":0,\"value\":\"Gram/Support\"},\"getInstalledAddOnVersion\":{\"exists\":false},\"getInstalledVersion\":{\"exists\":false},\"getLastPendingAction\":{\"exists\":false},\"getPendingAction\":{\"exists\":false},\"getTitle\":{\"exists\":false},\"isActive\":{\"exists\":true,\"public\":true,\"required\":0,\"total\":0,\"value\":false},\"isInstalled\":{\"exists\":true,\"public\":true,\"required\":0,\"total\":0,\"value\":false},\"isProcessing\":{\"exists\":false},\"present\":true},\"addon_row\":{\"active\":\"1\",\"addon_id\":\"Gram/Support\",\"is_legacy\":\"0\",\"is_processing\":\"1\",\"json_hash\":\"f3804541014a3dfde3b35323475c5dbcbb72ebb0d0c319d66385e9203628724d\",\"last_pending_action\":\"install:1\",\"title\":\"Gram Support\",\"version_id\":\"1000050\",\"version_string\":\"1.0.0 Alpha 3 Unified Fix 3\"},\"board_active\":\"0\",\"error_max\":45,\"errors_after_45\":0,\"manager\":{\"class\":\"XF\\\\AddOn\\\\Manager\",\"getAllAddOns\":{\"exists\":true,\"public\":true,\"required\":0,\"total\":0,\"value\":{\"Gram/Support\":{\"object\":\"XF\\\\AddOn\\\\AddOn\"},\"Newfi/Dogs\":{\"object\":\"XF\\\\AddOn\\\\AddOn\"},\"Newfi/Events\":{\"object\":\"XF\\\\AddOn\\\\AddOn\"},\"Newfi/Portal\":{\"object\":\"XF\\\\AddOn\\\\AddOn\"},\"XFMG\":{\"object\":\"XF\\\\AddOn\\\\AddOn\"},\"XFRM\":{\"object\":\"XF\\\\AddOn\\\\AddOn\"}}},\"getById\":{\"exists\":true,\"public\":true,\"required\":1,\"total\":1},\"getInstalledAddOns\":{\"exists\":true,\"public\":true,\"required\":0,\"total\":0,\"value\":{\"Newfi/Dogs\":{\"object\":\"XF\\\\AddOn\\\\AddOn\"},\"Newfi/Events\":{\"object\":\"XF\\\\AddOn\\\\AddOn\"},\"Newfi/Portal\":{\"object\":\"XF\\\\AddOn\\\\AddOn\"},\"XFMG\":{\"object\":\"XF\\\\AddOn\\\\AddOn\"},\"XFRM\":{\"object\":\"XF\\\\AddOn\\\\AddOn\"}}}},\"registry\":{\"type\":\"object\"},\"registry_rows\":[{\"bytes\":187,\"contains_gram\":true,\"data_key\":\"addOns\",\"sha256\":\"dca4ff8a040ff5651348c60446b8983b7bc1372d3403ee249da526c679c966e4\"},{\"bytes\":6,\"contains_gram\":false,\"data_key\":\"addOnsComposer\",\"sha256\":\"35786c7117b4e38d0f169239752ce71158266ae2f6e4aa230fbbb87bd699c0e3\"}]},\"state_after\":{\"addon_columns\":[\"addon_id\",\"title\",\"version_string\",\"version_id\",\"json_hash\",\"active\",\"is_legacy\",\"is_processing\",\"last_pending_action\"],\"addon_object\":{\"canUninstall\":{\"exists\":true,\"public\":true,\"required\":0,\"total\":0,\"value\":false},\"class\":\"XF\\\\AddOn\\\\AddOn\",\"getAddOnId\":{\"exists\":true,\"public\":true,\"required\":0,\"total\":0,\"value\":\"Gram/Support\"},\"getInstalledAddOnVersion\":{\"exists\":false},\"getInstalledVersion\":{\"exists\":false},\"getLastPendingAction\":{\"exists\":false},\"getPendingAction\":{\"exists\":false},\"getTitle\":{\"exists\":false},\"isActive\":{\"exists\":true,\"public\":true,\"required\":0,\"total\":0,\"value\":false},\"isInstalled\":{\"exists\":true,\"public\":true,\"required\":0,\"total\":0,\"value\":false},\"isProcessing\":{\"exists\":false},\"present\":true},\"addon_row\":{\"active\":\"1\",\"addon_id\":\"Gram/Support\",\"is_legacy\":\"0\",\"is_processing\":\"1\",\"json_hash\":\"f3804541014a3dfde3b35323475c5dbcbb72ebb0d0c319d66385e9203628724d\",\"last_pending_action\":\"install:1\",\"title\":\"Gram Support\",\"version_id\":\"1000050\",\"version_string\":\"1.0.0 Alpha 3 Unified Fix 3\"},\"board_active\":\"0\",\"error_max\":45,\"errors_after_45\":0,\"manager\":{\"class\":\"XF\\\\AddOn\\\\Manager\",\"getAllAddOns\":{\"exists\":true,\"public\":true,\"required\":0,\"total\":0,\"value\":{\"Gram/Support\":{\"object\":\"XF\\\\AddOn\\\\AddOn\"},\"Newfi/Dogs\":{\"object\":\"XF\\\\AddOn\\\\AddOn\"},\"Newfi/Events\":{\"object\":\"XF\\\\AddOn\\\\AddOn\"},\"Newfi/Portal\":{\"object\":\"XF\\\\AddOn\\\\AddOn\"},\"XFMG\":{\"object\":\"XF\\\\AddOn\\\\AddOn\"},\"XFRM\":{\"object\":\"XF\\\\AddOn\\\\AddOn\"}}},\"getById\":{\"exists\":true,\"public\":true,\"required\":1,\"total\":1},\"getInstalledAddOns\":{\"exists\":true,\"public\":true,\"required\":0,\"total\":0,\"value\":{\"Newfi/Dogs\":{\"object\":\"XF\\\\AddOn\\\\AddOn\"},\"Newfi/Events\":{\"object\":\"XF\\\\AddOn\\\\AddOn\"},\"Newfi/Portal\":{\"object\":\"XF\\\\AddOn\\\\AddOn\"},\"XFMG\":{\"object\":\"XF\\\\AddOn\\\\AddOn\"},\"XFRM\":{\"object\":\"XF\\\\AddOn\\\\AddOn\"}}}},\"registry\":{\"type\":\"object\"},\"registry_rows\":[{\"bytes\":187,\"contains_gram\":true,\"data_key\":\"addOns\",\"sha256\":\"dca4ff8a040ff5651348c60446b8983b7bc1372d3403ee249da526c679c966e4\"},{\"bytes\":6,\"contains_gram\":false,\"data_key\":\"addOnsComposer\",\"sha256\":\"35786c7117b4e38d0f169239752ce71158266ae2f6e4aa230fbbb87bd699c0e3\"}]},\"status\":\"OK\",\"uninstall_help\":{\"lines\":[\"Description:\",\"Uninstalls the specified add-on\",\"Usage:\",\"xf:addon-uninstall [options] [--] \",\"xf-addon:uninstall\",\"Arguments:\",\"id Add-On ID\",\"Options:\",\"-f, --force Skip verifying that the add-on is uninstallable\",\"-h, --help Display help for the given command. When no command is given display help for the list command\",\"-q, --quiet Do not output any message\",\"-V, --version Display this application version\",\"--ansi|--no-ansi Force (or disable --no-ansi) ANSI output\",\"-n, --no-interaction Do not ask any interactive question\",\"-v|vv|vvv, --verbose Increase the verbosity of messages: 1 for normal output, 2 for more verbose output and 3 for debug\"],\"rc\":0,\"stderr_sha256\":\"\"}}\nSUPPORT066_HOLDS=[]\nSUPPORT066_DECISION=NARROW_PROCESSING_STATE_CAPTURED\nSUPPORT066_MUTATION_SCOPE=NONE_READ_ONLY\nHOMELAB_RESULT_CONTRACT={\"changes_made\":false,\"command_id\":\"SUPPORT-260909-GRAM-XF-PROCESSING-NARROW-066\",\"rollback_restored\":null,\"rollback_started\":false,\"status\":\"OK\",\"version\":1}\nSUPPORT066_END\n" } diff --git a/runtime/latest.txt b/runtime/latest.txt index d816a12f..467a711b 100644 --- a/runtime/latest.txt +++ b/runtime/latest.txt @@ -1,15 +1,15 @@ CHAT_OUTPUT_BEGIN -COMMAND_ID=SUPPORT-260909-GRAM-XF-PROCESSING-RCA-065 +COMMAND_ID=SUPPORT-260909-GRAM-XF-PROCESSING-NARROW-066 STATUS=OK RC=0 HOST=pve01 MODE=read-only -COMPONENT=gram-support-processing-state-rca +COMPONENT=gram-support-processing-narrow REFERENCE_REGISTER_CHECK=OK REFERENCE_SHA256=5a3d8e5154c41cb582a4e0aca68090be1f0138918bf82131a948df326f9d8d66 ERROR_REGISTER_CHECK=OK ERROR_REGISTER_SHA256=3b09a553ec0f527ed3afeed4753f52a74ee3036045bbfb3c685e9f8af4ba7ba0 -COMMAND_SHA256=58650c7036826de2b367e43288c37a4bd74fa37fd38895b6cd899c5b17b53b68 +COMMAND_SHA256=b3716049942ceaea06095b5ef78a11b817e642afcc6903f53a48e9f209af6efa DUPLICATE_FAILED_COMMAND_BLOCKED=false EXECUTION_STARTED=true CHANGE_DECLARED=false @@ -24,21 +24,21 @@ MUTATION_OUTCOME=NO_MUTATION SANITIZED=yes SECRETS_INCLUDED=no PRIVATE_ADDRESSES_INCLUDED=no -RAW_EVIDENCE_SHA256=9fff9616621e2e34c86e9d1b10d3848cacb6aea9487d9a67a849be45c240506d -SANITIZED_OUTPUT_SHA256=9fff9616621e2e34c86e9d1b10d3848cacb6aea9487d9a67a849be45c240506d +RAW_EVIDENCE_SHA256=f3bacd113632355b0404ed76453af3e803d539bb8c332baf6b14b126f66f47ee +SANITIZED_OUTPUT_SHA256=f3bacd113632355b0404ed76453af3e803d539bb8c332baf6b14b126f66f47ee OUTPUT_BEGIN -SUPPORT065_BEGIN +SUPPORT066_BEGIN ERROR_REGISTER_CHECK=OK REFERENCE_CHECK=OK AUTHORITY_CHECK_SCOPE=READABILITY_ONLY_INCIDENTS_NOT_CLOSED RUNNER_SHA256=b248a4c32c9cc64e5747e7dce6c7fc0a23f5124a77c71ce72e27a81aceae9d2d -SUPPORT065_QGA_STATE={"exitcode":0,"state":"COMPLETE"} -SUPPORT065_VM211={"addon_list":{"rc":0,"stderr":"","stdout":"{\n \"addons\": [\n {\n \"addon_id\": \"Newfi\\/Dogs\",\n \"title\": \"Newfi Dogs\",\n \"version_string\": \"1.0.0 Alpha 1\",\n \"version_id\": 1000010,\n \"active\": true,\n \"legacy\": false,\n \"is_processing\": false,\n \"last_pending_action\": null,\n \"developer\": \"Newfi\",\n \"path\": \"\\/var\\/www\\/forums\\/newfi\\/public\\/src\\/addons\\/Newfi\\/Dogs\"\n },\n {\n \"addon_id\": \"Newfi\\/Events\",\n \"title\": \"Newfi Events\",\n \"version_string\": \"1.0.0 Alpha 1\",\n \"version_id\": 1000010,\n \"active\": true,\n \"legacy\": false,\n \"is_processing\": false,\n \"last_pending_action\": null,\n \"developer\": \"Newfi\",\n \"path\": \"\\/var\\/www\\/forums\\/newfi\\/public\\/src\\/addons\\/Newfi\\/Events\"\n },\n {\n \"addon_id\": \"Newfi\\/Portal\",\n \"title\": \"Newfi Portal\",\n \"version_string\": \"1.0.0 Alpha 1\",\n \"version_id\": 1000010,\n \"active\": true,\n \"legacy\": false,\n \"is_processing\": false,\n \"last_pending_action\": null,\n \"developer\": \"Newfi\",\n \"path\": \"\\/var\\/www\\/forums\\/newfi\\/public\\/src\\/addons\\/Newfi\\/Portal\"\n },\n {\n \"addon_id\": \"XFMG\",\n \"title\": \"XenForo Media Gallery\",\n \"version_string\": \"2.3.11\",\n \"version_id\": 902031170,\n \"active\": true,\n \"legacy\": false,\n \"is_processing\": false,\n \"last_pending_action\": null,\n \"developer\": \"XenForo Ltd.\",\n \"path\": \"\\/var\\/www\\/forums\\/newfi\\/public\\/src\\/addons\\/XFMG\"\n },\n {\n \"addon_id\": \"XFRM\",\n \"title\": \"XenForo Resource Manager\",\n \"version_string\": \"2.3.11\",\n \"version_id\": 2031170,\n \"active\": true,\n \"legacy\": false,\n \"is_processing\": false,\n \"last_pending_action\": null,\n \"developer\": \"XenForo Ltd.\",\n \"path\": \"\\/var\\/www\\/forums\\/newfi\\/public\\/src\\/addons\\/XFRM\"\n }\n ],\n \"summary\": {\n \"total\": 5,\n \"active\": 5,\n \"inactive\": 0\n }\n}"},"command_id":"SUPPORT-260909-GRAM-XF-PROCESSING-RCA-065","decision":"PROCESSING_STATE_AND_UNINSTALL_SOURCE_CAPTURED","guest":"newfi-staging","holds":[],"identity_ok":true,"list_help":{"rc":0,"stderr":"","stdout":"Description:\n Lists installed add-ons\n\nUsage:\n xf:addon-list [options]\n xf-addon:list\n\nOptions:\n --active Only show active add-ons\n --inactive Only show inactive add-ons\n --json Output as JSON\n -h, --help Display help for the given command. When no command is given display help for the list command\n -q, --quiet Do not output any message\n -V, --version Display this application version\n --ansi|--no-ansi Force (or disable --no-ansi) ANSI output\n -n, --no-interaction Do not ask any interactive question\n -v|vv|vvv, --verbose Increase the verbosity of messages: 1 for normal output, 2 for more verbose output and 3 for debug"},"php_state":{"data":{"addon_columns":["addon_id","title","version_string","version_id","json_hash","active","is_legacy","is_processing","last_pending_action"],"addon_row":{"active":"1","addon_id":"Gram/Support","is_legacy":"0","is_processing":"1","json_hash":"f3804541014a3dfde3b35323475c5dbcbb72ebb0d0c319d66385e9203628724d","last_pending_action":"install:1","title":"Gram Support","version_id":"1000050","version_string":"1.0.0 Alpha 3 Unified Fix 3"},"board_active":"0","error_max":45,"errors_after_45":0,"manager_class":"XF\\AddOn\\Manager","manager_getById":{"canUninstall":false,"class":"XF\\AddOn\\AddOn","getSetup":"Gram\\Support\\Setup","isActive":false,"isInstalled":false},"manager_methods":{"getAllAddOns":{"public":true,"required":0,"total":0},"getById":{"public":true,"required":1,"total":1},"getInstalledAddOns":{"public":true,"required":0,"total":0}}},"rc":0,"stderr_sha256":""},"scope":"READ_ONLY_NO_MUTATION","source_evidence":[{"file":"src/XF/Cli/Command/AddOn/UninstallStep.php","matches":[{"line":1,"text":"addArgument("},{"line":17,"text":"\t\t\t'step',"},{"line":18,"text":"\t\t\tInputArgument::REQUIRED,"},{"line":19,"text":"\t\t\t'The step number to run.'"},{"line":20,"text":"\t\t);"},{"line":21,"text":"\t}"},{"line":22,"text":"}"}],"sha256":"d69b287acd3ea5c02bf23492e1bdef465fb75f22f00b45acdb4ffafe547260e5"},{"file":"src/XF/Cli/Command/AddOnUninstall.php","matches":[{"line":2,"text":""},{"line":3,"text":"namespace XF\\Cli\\Command;"},{"line":4,"text":""},{"line":5,"text":"use Symfony\\Component\\Console\\Helper\\QuestionHelper;"},{"line":6,"text":"use Symfony\\Component\\Console\\Input\\InputArgument;"},{"line":7,"text":"use Symfony\\Component\\Console\\Input\\InputInterface;"},{"line":8,"text":"use Symfony\\Component\\Console\\Input\\InputOption;"},{"line":9,"text":"use Symfony\\Component\\Console\\Output\\OutputInterface;"},{"line":10,"text":"use Symfony\\Component\\Console\\Question\\ConfirmationQuestion;"},{"line":11,"text":""},{"line":12,"text":"class AddOnUninstall extends AbstractCommand"},{"line":13,"text":"{"},{"line":14,"text":"\tuse AddOnActionTrait;"},{"line":15,"text":"\tuse JobRunnerTrait;"},{"line":16,"text":""},{"line":17,"text":"\tprotected function configure()"},{"line":18,"text":"\t{"},{"line":19,"text":"\t\t$this"},{"line":20,"text":"\t\t\t->setName('xf:addon-uninstall')"},{"line":21,"text":"\t\t\t->setAliases(['xf-addon:uninstall'])"},{"line":22,"text":"\t\t\t->setDescription('Uninstalls the specified add-on')"},{"line":23,"text":"\t\t\t->addArgument("},{"line":24,"text":"\t\t\t\t'id',"},{"line":25,"text":"\t\t\t\tInputArgument::REQUIRED,"},{"line":26,"text":"\t\t\t\t'Add-On ID'"},{"line":27,"text":"\t\t\t)"},{"line":28,"text":"\t\t\t->addOption("},{"line":29,"text":"\t\t\t\t'force',"},{"line":30,"text":"\t\t\t\t'f',"},{"line":31,"text":"\t\t\t\tInputOption::VALUE_NONE,"},{"line":32,"text":"\t\t\t\t'Skip verifying that the add-on is uninstallable'"},{"line":33,"text":"\t\t\t);"},{"line":34,"text":"\t}"},{"line":35,"text":""},{"line":36,"text":"\tprotected function execute(InputInterface $input, OutputInterface $output)"},{"line":37,"text":"\t{"},{"line":38,"text":"\t\t$id = $input->getArgument('id');"},{"line":39,"text":""},{"line":40,"text":"\t\t$addOn = $this->checkInstalledAddOn($id, $error);"},{"line":41,"text":"\t\tif (!$addOn)"},{"line":42,"text":"\t\t{"},{"line":43,"text":"\t\t\t$output->writeln('' . $error . '');"},{"line":44,"text":"\t\t\treturn 1;"},{"line":45,"text":"\t\t}"},{"line":46,"text":""},{"line":47,"text":"\t\tif (!$addOn->canUninstall() && !$input->getOption('force'))"},{"line":48,"text":"\t\t{"},{"line":49,"text":"\t\t\t$output->writeln(\"\" . \\XF::phrase('this_add_on_cannot_be_uninstalled_like_files_missing') . \"\");"},{"line":50,"text":"\t\t\treturn 1;"},{"line":51,"text":"\t\t}"},{"line":52,"text":""},{"line":53,"text":"\t\t/** @var QuestionHelper $helper */"},{"line":54,"text":"\t\t$helper = $this->getHelper('question');"},{"line":55,"text":""},{"line":56,"text":"\t\t$question = new ConfirmationQuestion(\"\" . \\XF::phrase('please_confirm_that_you_want_to_uninstall_following_add_on') . ': (' . $addOn->title . ' ' . $addOn->version_string . \") (y/n)\");"},{"line":57,"text":"\t\t$response = $helper->ask($input, $output, $question);"},{"line":58,"text":"\t\tif (!$response)"},{"line":59,"text":"\t\t{"},{"line":60,"text":"\t\t\treturn 1;"},{"line":61,"text":"\t\t}"},{"line":62,"text":""},{"line":63,"text":"\t\t// make sure any errors get logged here"},{"line":64,"text":"\t\t\\XF::app()->error()->setIgnorePendingUpgrade(true);"},{"line":65,"text":""},{"line":66,"text":"\t\t$addOn->preUninstall();"},{"line":67,"text":""},{"line":68,"text":"\t\t$this->runSubAction($output, $addOn, 'uninstall');"},{"line":69,"text":"\t\t$this->runSubAction($output, $addOn, 'uninstall-data');"},{"line":70,"text":"\t\t$this->runSubAction($output, $addOn, 'post-uninstall');"},{"line":71,"text":""},{"line":72,"text":"\t\treturn 0;"},{"line":73,"text":"\t}"},{"line":74,"text":"}"}],"sha256":"6dc768f60efd4af161b549cd54c01ae8922326cf7fd230b8ef93403bf8dba90c"},{"file":"src/XF/AddOn/AddOn.php","matches":[{"line":45,"text":"\t/**"},{"line":46,"text":"\t * @var \\XF\\Entity\\AddOn"},{"line":47,"text":"\t */"},{"line":48,"text":"\tprotected $installedAddOn;"},{"line":49,"text":""},{"line":50,"text":"\t/**"},{"line":51,"text":"\t * @var AbstractSetup"},{"line":52,"text":"\t */"},{"line":53,"text":"\tprotected $setup;"},{"line":54,"text":""},{"line":55,"text":"\tprotected $addOnId;"},{"line":56,"text":"\tprotected $legacyAddOnId;"},{"line":57,"text":""},{"line":58,"text":"\tprotected $addOnDir;"},{"line":59,"text":"\tprotected $buildDir;"},{"line":60,"text":"\tprotected $dataDir;"},{"line":61,"text":"\tprotected $filesDir;"},{"line":62,"text":"\tprotected $outputDir;"},{"line":63,"text":"\tprotected $releasesDir;"},{"line":64,"text":""},{"line":65,"text":"\tprotected $jsonPath;"},{"line":66,"text":"\tprotected $json = [];"},{"line":67,"text":""},{"line":68,"text":"\tprotected $buildJsonPath;"},{"line":69,"text":"\tprotected $buildJson = [];"},{"line":70,"text":""},{"line":71,"text":"\tprotected $missingFiles = [];"},{"line":72,"text":""},{"line":73,"text":"\tprotected $addOnHashes;"},{"line":74,"text":""},{"line":75,"text":"\tpublic function __construct($addOnOrId, Manager $manager)"},{"line":76,"text":"\t{"},{"line":77,"text":"\t\t$this->manager = $manager;"},{"line":78,"text":""},{"line":79,"text":"\t\tif ($addOnOrId instanceof \\XF\\Entity\\AddOn)"},{"line":80,"text":"\t\t{"},{"line":81,"text":"\t\t\t$this->installedAddOn = $addOnOrId;"},{"line":82,"text":"\t\t\t$this->addOnId = $addOnOrId->addon_id;"},{"line":83,"text":"\t\t}"},{"line":84,"text":"\t\telse"},{"line":85,"text":"\t\t{"},{"line":86,"text":"\t\t\t$this->addOnId = $addOnOrId;"},{"line":87,"text":"\t\t}"},{"line":88,"text":""},{"line":89,"text":"\t\t$ds = \\XF::$DS;"},{"line":90,"text":""},{"line":91,"text":"\t\t$this->addOnDir = \\XF::getAddOnDirectory() . $ds . $this->prepareAddOnIdForPath();"},{"line":92,"text":""},{"line":93,"text":"\t\t// Resolve symlinks to ensure consistent path handling"},{"line":94,"text":"\t\t$realAddOnDir = realpath($this->addOnDir);"},{"line":95,"text":"\t\tif ($realAddOnDir !== false)"},{"line":96,"text":"\t\t{"},{"line":97,"text":"\t\t\t$this->addOnDir = $realAddOnDir;"},{"line":98,"text":"\t\t}"},{"line":99,"text":""},{"line":100,"text":"\t\t$this->buildDir = $this->addOnDir . $ds . '_build';"},{"line":101,"text":"\t\t$this->dataDir = $this->addOnDir . $ds . '_data';"},{"line":102,"text":"\t\t$this->filesDir = $this->addOnDir . $ds . '_files';"},{"line":103,"text":"\t\t$this->outputDir = $this->addOnDir . $ds . '_output';"},{"line":104,"text":"\t\t$this->releasesDir = $this->addOnDir . $ds . '_releases';"},{"line":105,"text":""},{"line":106,"text":"\t\t$this->jsonPath = $this->addOnDir . $ds . 'addon.json';"},{"line":107,"text":"\t\tif (file_exists($this->jsonPath))"},{"line":108,"text":"\t\t{"},{"line":109,"text":"\t\t\t$this->json = $this->prepareJsonFile("},{"line":110,"text":"\t\t\t\tjson_decode(file_get_contents($this->jsonPath), true) ?: []"},{"line":111,"text":"\t\t\t);"},{"line":112,"text":"\t\t}"},{"line":113,"text":"\t\telse"},{"line":114,"text":"\t\t{"},{"line":115,"text":"\t\t\t$this->missingFiles[] = 'addon.json';"},{"line":116,"text":"\t\t}"},{"line":117,"text":""},{"line":118,"text":"\t\tif (!$this->installedAddOn && !empty($this->json['legacy_addon_id']))"},{"line":119,"text":"\t\t{"},{"line":120,"text":"\t\t\t$this->legacyAddOnId = $this->json['legacy_addon_id'];"},{"line":121,"text":"\t\t\t$this->installedAddOn = \\XF::em()->find(\\XF\\Entity\\AddOn::class, $this->legacyAddOnId);"},{"line":122,"text":"\t\t}"},{"line":123,"text":""},{"line":124,"text":"\t\t$this->buildJsonPath = $this->addOnDir . $ds . 'build.json';"},{"line":125,"text":"\t\t$this->buildJson = ["},{"line":126,"text":"\t\t\t'additional_files' => [],"},{"line":127,"text":"\t\t\t'minify' => [],"},{"line":128,"text":"\t\t\t'rollup' => [],"},{"line":129,"text":"\t\t\t'exec' => [],"},{"line":130,"text":"\t\t];"},{"line":131,"text":"\t\tif (file_exists($this->buildJsonPath))"},{"line":132,"text":"\t\t{"},{"line":133,"text":"\t\t\t$buildJson = @json_decode(file_get_contents($this->buildJsonPath), true);"},{"line":134,"text":""},{"line":135,"text":"\t\t\t$this->buildJson = array_replace("},{"line":136,"text":"\t\t\t\t$this->buildJson,"},{"line":137,"text":"\t\t\t\t$buildJson ?: []"},{"line":138,"text":"\t\t\t);"},{"line":139,"text":"\t\t}"},{"line":140,"text":"\t}"},{"line":141,"text":""},{"line":142,"text":"\tpublic function getInstalledAddOn()"},{"line":143,"text":"\t{"},{"line":144,"text":"\t\treturn $this->installedAddOn;"},{"line":145,"text":"\t}"},{"line":146,"text":""},{"line":147,"text":"\tpublic function getAddOnId()"},{"line":148,"text":"\t{"},{"line":149,"text":"\t\treturn $this->addOnId;"},{"line":150,"text":"\t}"},{"line":151,"text":""},{"line":152,"text":"\tpublic function getAddOnIdUrl()"},{"line":153,"text":"\t{"},{"line":154,"text":"\t\treturn \\XF::app()->repository(AddOnRepository::class)->convertAddOnIdToUrlVersion($this->getAddOnId());"},{"line":155,"text":"\t}"},{"line":156,"text":""},{"line":157,"text":"\tpublic function prepareVersionForFilename()"},{"line":158,"text":"\t{"},{"line":159,"text":"\t\t$versionString = preg_replace('/[^a-z0-9-_. ]/i', '', $this->version_string);"},{"line":160,"text":"\t\treturn trim(preg_replace('/\\s{2,}/', ' ', $versionString));"},{"line":161,"text":"\t}"},{"line":162,"text":""},{"line":163,"text":"\tpublic function prepareAddOnIdForFilename()"},{"line":164,"text":"\t{"},{"line":165,"text":"\t\tif (strpos($this->addOnId, '/') !== false)"},{"line":166,"text":"\t\t{"},{"line":167,"text":"\t\t\treturn str_replace('/', '-', $this->addOnId);"},{"line":168,"text":"\t\t}"},{"line":169,"text":"\t\telse"},{"line":170,"text":"\t\t{"},{"line":171,"text":"\t\t\treturn $this->addOnId;"},{"line":172,"text":"\t\t}"},{"line":173,"text":"\t}"},{"line":174,"text":""},{"line":175,"text":"\tpublic function prepareAddOnIdForPath()"},{"line":176,"text":"\t{"},{"line":177,"text":"\t\tif (strpos($this->addOnId, '/') !== false)"},{"line":178,"text":"\t\t{"},{"line":179,"text":"\t\t\treturn str_replace('/', \\XF::$DS, $this->addOnId);"},{"line":180,"text":"\t\t}"},{"line":181,"text":"\t\telse"},{"line":182,"text":"\t\t{"},{"line":183,"text":"\t\t\treturn $this->addOnId;"},{"line":184,"text":"\t\t}"},{"line":185,"text":"\t}"},{"line":186,"text":""},{"line":187,"text":"\tpublic function prepareAddOnIdForClass()"},{"line":188,"text":"\t{"},{"line":189,"text":"\t\tif (strpos($this->addOnId, '/') !== false)"},{"line":190,"text":"\t\t{"},{"line":191,"text":"\t\t\treturn str_replace('/', '\\\\', $this->addOnId);"},{"line":192,"text":"\t\t}"},{"line":193,"text":"\t\telse"},{"line":194,"text":"\t\t{"},{"line":195,"text":"\t\t\treturn $this->addOnId;"},{"line":196,"text":"\t\t}"},{"line":197,"text":"\t}"},{"line":198,"text":""},{"line":199,"text":"\tpublic function getMissingFiles()"},{"line":200,"text":"\t{"},{"line":201,"text":"\t\treturn $this->missingFiles;"},{"line":202,"text":"\t}"},{"line":203,"text":""},{"line":204,"text":"\tpublic function getAddOnDirectory()"},{"line":205,"text":"\t{"},{"line":206,"text":"\t\treturn $this->addOnDir;"},{"line":207,"text":"\t}"},{"line":208,"text":""},{"line":209,"text":"\tpublic function getBuildDirectory()"},{"line":210,"text":"\t{"},{"line":211,"text":"\t\treturn $this->buildDir;"},{"line":212,"text":"\t}"},{"line":213,"text":""},{"line":214,"text":"\tpublic function getDataDirectory()"},{"line":215,"text":"\t{"},{"line":216,"text":"\t\treturn $this->dataDir;"},{"line":221,"text":"\t\treturn $this->filesDir;"},{"line":222,"text":"\t}"},{"line":223,"text":""},{"line":224,"text":"\tpublic function getReleasesDirectory()"},{"line":225,"text":"\t{"},{"line":226,"text":"\t\treturn $this->releasesDir;"},{"line":227,"text":"\t}"},{"line":228,"text":""}],"sha256":"0e0346a046fff6bde9850cb53e9dc0d0b5379387029dc16925e562fa141ab422"},{"file":"src/XF/AddOn/StepRunnerUninstallTrait.php","matches":[{"line":1,"text":" 0,"},{"line":21,"text":"\t\t], $stepParams);"},{"line":22,"text":""},{"line":23,"text":"\t\t$step = $stepParams['step'];"},{"line":24,"text":"\t\tif (!$step)"},{"line":25,"text":"\t\t{"},{"line":26,"text":"\t\t\t$step = $this->getUninstallResumeStep();"},{"line":27,"text":"\t\t}"},{"line":28,"text":"\t\treturn $this->uninstallStepRunner($step, $stepParams);"},{"line":29,"text":"\t}"},{"line":30,"text":""},{"line":31,"text":"\tprivate function getUninstallResumeStep()"},{"line":32,"text":"\t{"},{"line":33,"text":"\t\t$installedAddOn = $this->addOn->getInstalledAddOn();"},{"line":34,"text":"\t\tif ($installedAddOn)"},{"line":35,"text":"\t\t{"},{"line":36,"text":"\t\t\t$lastActionStep = $installedAddOn->getLastActionStep('uninstall');"},{"line":37,"text":"\t\t\tif ($lastActionStep)"},{"line":38,"text":"\t\t\t{"},{"line":39,"text":"\t\t\t\treturn $lastActionStep + 1; // this is the last completed step, so resume with the next"},{"line":40,"text":"\t\t\t}"},{"line":41,"text":"\t\t}"},{"line":42,"text":""},{"line":43,"text":"\t\treturn 1;"},{"line":44,"text":"\t}"},{"line":45,"text":""},{"line":46,"text":"\t/**"},{"line":47,"text":"\t * @param integer $step"},{"line":48,"text":"\t * @param array $stepParams"},{"line":49,"text":"\t *"},{"line":50,"text":"\t * @return null|StepResult"},{"line":51,"text":"\t */"},{"line":52,"text":"\tprivate function uninstallStepRunner($step, array $stepParams)"},{"line":53,"text":"\t{"},{"line":54,"text":"\t\t$fnPrefix = 'uninstallStep';"},{"line":55,"text":"\t\t$fn = $fnPrefix . $step;"},{"line":56,"text":"\t\tif (!method_exists($this, $fn))"},{"line":57,"text":"\t\t{"},{"line":58,"text":"\t\t\treturn null;"},{"line":59,"text":"\t\t}"},{"line":60,"text":""},{"line":61,"text":"\t\t$result = $this->$fn($stepParams);"},{"line":62,"text":"\t\tif ($result === null || $result === true)"},{"line":63,"text":"\t\t{"},{"line":64,"text":"\t\t\t$result = new StepResult(true);"},{"line":65,"text":"\t\t}"},{"line":66,"text":"\t\telse if (is_array($result))"},{"line":67,"text":"\t\t{"},{"line":68,"text":"\t\t\t$result = new StepResult(false, $result);"},{"line":69,"text":"\t\t}"},{"line":70,"text":""},{"line":71,"text":"\t\tif (!($result instanceof StepResult))"},{"line":72,"text":"\t\t{"},{"line":73,"text":"\t\t\tthrow new \\LogicException(\"Must return a StepResult object\");"},{"line":74,"text":"\t\t}"},{"line":75,"text":""},{"line":76,"text":"\t\t$result->step = $step;"},{"line":77,"text":""},{"line":78,"text":"\t\tif ($result->complete)"},{"line":79,"text":"\t\t{"},{"line":80,"text":"\t\t\t$this->addOn->updatePendingAction('uninstall', $result->step);"},{"line":81,"text":""},{"line":82,"text":"\t\t\t$nextStep = $step + 1;"},{"line":83,"text":"\t\t\t$nextFn = $fnPrefix . $nextStep;"},{"line":84,"text":"\t\t\tif (!method_exists($this, $nextFn))"},{"line":85,"text":"\t\t\t{"},{"line":86,"text":"\t\t\t\treturn null;"},{"line":87,"text":"\t\t\t}"},{"line":88,"text":""},{"line":89,"text":"\t\t\t$result = new StepResult(false, [], $nextStep);"},{"line":90,"text":"\t\t}"},{"line":91,"text":""},{"line":92,"text":"\t\treturn $result;"},{"line":93,"text":"\t}"},{"line":94,"text":"}"}],"sha256":"e58a9ab9c30e3cf3c41a0be392e8c5ac37f744578f7b91f76d663139649c49a9"}],"state_after":{"addon_columns":["addon_id","title","version_string","version_id","json_hash","active","is_legacy","is_processing","last_pending_action"],"addon_row":{"active":"1","addon_id":"Gram/Support","is_legacy":"0","is_processing":"1","json_hash":"f3804541014a3dfde3b35323475c5dbcbb72ebb0d0c319d66385e9203628724d","last_pending_action":"install:1","title":"Gram Support","version_id":"1000050","version_string":"1.0.0 Alpha 3 Unified Fix 3"},"board_active":"0","error_max":45,"errors_after_45":0,"manager_class":"XF\\AddOn\\Manager","manager_getById":{"canUninstall":false,"class":"XF\\AddOn\\AddOn","getSetup":"Gram\\Support\\Setup","isActive":false,"isInstalled":false},"manager_methods":{"getAllAddOns":{"public":true,"required":0,"total":0},"getById":{"public":true,"required":1,"total":1},"getInstalledAddOns":{"public":true,"required":0,"total":0}}},"status":"OK","uninstall_help":{"rc":0,"stderr":"","stdout":"Description:\n Uninstalls the specified add-on\n\nUsage:\n xf:addon-uninstall [options] [--] \n xf-addon:uninstall\n\nArguments:\n id Add-On ID\n\nOptions:\n -f, --force Skip verifying that the add-on is uninstallable\n -h, --help Display help for the given command. When no command is given display help for the list command\n -q, --quiet Do not output any message\n -V, --version Display this application version\n --ansi|--no-ansi Force (or disable --no-ansi) ANSI output\n -n, --no-interaction Do not ask any interactive question\n -v|vv|vvv, --verbose Increase the verbosity of messages: 1 for normal output, 2 for more verbose output and 3 for debug"}} -SUPPORT065_HOLDS=[] -SUPPORT065_DECISION=PROCESSING_STATE_AND_UNINSTALL_SOURCE_CAPTURED -SUPPORT065_MUTATION_SCOPE=NONE_READ_ONLY -HOMELAB_RESULT_CONTRACT={"changes_made":false,"command_id":"SUPPORT-260909-GRAM-XF-PROCESSING-RCA-065","rollback_restored":null,"rollback_started":false,"status":"OK","version":1} -SUPPORT065_END +SUPPORT066_QGA_STATE={"exitcode":0,"state":"COMPLETE"} +SUPPORT066_VM211={"command_id":"SUPPORT-260909-GRAM-XF-PROCESSING-NARROW-066","decision":"NARROW_PROCESSING_STATE_CAPTURED","guest":"newfi-staging","holds":[],"identity_ok":true,"probe":{"rc":0,"stderr_sha256":""},"probe_after":{"rc":0,"stderr_sha256":""},"scope":"READ_ONLY_NO_MUTATION","source_evidence":[{"file":"src/XF/Cli/Command/AddOn/AbstractSetupStep.php","matches":[{"line":42,"text":"\t{"},{"line":43,"text":"\t\t$id = $input->getArgument('id');"},{"line":44,"text":""},{"line":45,"text":"\t\t$addOn = $this->checkEditableAddOn($id, $error);"},{"line":46,"text":"\t\tif (!$addOn)"},{"line":47,"text":"\t\t{"},{"line":48,"text":"\t\t\t$output->writeln('' . $error . '');"},{"line":49,"text":"\t\t\treturn 1;"},{"line":50,"text":"\t\t}"},{"line":51,"text":""},{"line":52,"text":"\t\t$setup = $addOn->getSetup();"},{"line":53,"text":""},{"line":54,"text":"\t\tif (!$setup)"},{"line":55,"text":"\t\t{"},{"line":56,"text":"\t\t\t$output->writeln(\"Setup class for add-on could not be found.\");"},{"line":57,"text":"\t\t\treturn 1;"},{"line":58,"text":"\t\t}"},{"line":59,"text":""},{"line":60,"text":"\t\t$step = $input->getArgument('step');"},{"line":61,"text":"\t\t$version = null;"},{"line":62,"text":"\t\t$params = [];"},{"line":63,"text":""},{"line":64,"text":"\t\t$stepType = $this->getStepType();"},{"line":65,"text":"\t\tif ($stepType == 'upgrade')"},{"line":66,"text":"\t\t{"},{"line":67,"text":"\t\t\t$version = $input->getArgument('version');"},{"line":68,"text":"\t\t}"},{"line":69,"text":""},{"line":70,"text":"\t\t$setup->prepareForAction($stepType);"},{"line":71,"text":""},{"line":72,"text":"\t\tdo"},{"line":73,"text":"\t\t{"},{"line":74,"text":"\t\t\t$result = $this->runStep($setup, $output, $stepType, $step, $version, $params);"},{"line":75,"text":"\t\t\tif (!($result instanceof StepResult))"},{"line":76,"text":"\t\t\t{"},{"line":77,"text":"\t\t\t\t$this->clearStatus($output, \"Must return a StepResult object.\");"},{"line":78,"text":"\t\t\t\treturn 1;"},{"line":79,"text":"\t\t\t}"},{"line":80,"text":"\t\t\telse"},{"line":81,"text":"\t\t\t{"},{"line":82,"text":"\t\t\t\tif ($result->complete)"},{"line":83,"text":"\t\t\t\t{"},{"line":84,"text":"\t\t\t\t\t$loop = false;"},{"line":85,"text":"\t\t\t\t}"},{"line":86,"text":"\t\t\t\telse if (is_int($result))"},{"line":87,"text":"\t\t\t\t{"},{"line":88,"text":"\t\t\t\t\t$loop = false;"},{"line":89,"text":"\t\t\t\t}"},{"line":90,"text":"\t\t\t\telse"},{"line":91,"text":"\t\t\t\t{"},{"line":92,"text":"\t\t\t\t\t$params = $result->params;"},{"line":93,"text":"\t\t\t\t\t$loop = true;"},{"line":104,"text":"\tprotected function runStep(AbstractSetup $setup, OutputInterface $output, $stepType, $step, $version = null, array $params = [])"},{"line":105,"text":"\t{"},{"line":106,"text":"\t\t$method = $stepType;"},{"line":107,"text":""},{"line":108,"text":"\t\tswitch ($method)"},{"line":109,"text":"\t\t{"},{"line":110,"text":"\t\t\tcase 'install':"},{"line":111,"text":"\t\t\tcase 'uninstall':"},{"line":112,"text":"\t\t\t\tif ($step)"},{"line":113,"text":"\t\t\t\t{"},{"line":114,"text":"\t\t\t\t\t$method .= 'Step' . $step;"},{"line":115,"text":"\t\t\t\t}"},{"line":116,"text":"\t\t\t\tbreak;"},{"line":117,"text":""},{"line":118,"text":"\t\t\tcase 'upgrade':"},{"line":119,"text":"\t\t\t\tif ($version && $step)"},{"line":120,"text":"\t\t\t\t{"},{"line":121,"text":"\t\t\t\t\t$method .= $version . 'Step' . $step;"},{"line":122,"text":"\t\t\t\t}"},{"line":123,"text":"\t\t\t\tbreak;"},{"line":124,"text":"\t\t}"},{"line":125,"text":""},{"line":126,"text":"\t\tif (!method_exists($setup, $method))"}],"sha256":"86ac6e9eda2202a75f3566a6bf20b14b5cc5171a823e0a23de0e66d0e8c0a8b7"},{"file":"src/XF/Cli/Command/AddOn/Create.php","matches":[{"line":40,"text":"\t\tif ($devOutput->isAddOnSkipped($addOnId))"},{"line":41,"text":"\t\t{"},{"line":42,"text":"\t\t\t$output->writeln(\"Development output for this add-on ID has been disabled. Cannot continue.\");"},{"line":43,"text":"\t\t\tif (strtolower(substr($addOnId, 0, 2)) == 'xf')"},{"line":44,"text":"\t\t\t{"},{"line":45,"text":"\t\t\t\t$output->writeln(\"Note: use of add-on IDs starting with 'xf' is strongly discouraged.\");"},{"line":46,"text":"\t\t\t}"},{"line":47,"text":"\t\t\treturn 1;"},{"line":48,"text":"\t\t}"},{"line":49,"text":""},{"line":50,"text":"\t\t$checkPath = \\XF::getAddOnDirectory();"},{"line":51,"text":""},{"line":52,"text":"\t\t$addOnManager = \\XF::app()->addOnManager();"},{"line":53,"text":"\t\tforeach ($addOnManager->getAllAddOns() AS $existingAddOnId => $existingAddOn)"},{"line":54,"text":"\t\t{"},{"line":55,"text":"\t\t\tif ($existingAddOnId !== $addOnId && strcasecmp($existingAddOnId, $addOnId) === 0)"},{"line":56,"text":"\t\t\t{"},{"line":57,"text":"\t\t\t\t$output->writeln(\"Add-on ID '{$addOnId}' conflicts with existing add-on '{$existingAddOnId}' (case mismatch).\");"},{"line":58,"text":"\t\t\t\treturn 1;"},{"line":59,"text":"\t\t\t}"},{"line":60,"text":"\t\t}"},{"line":61,"text":""},{"line":62,"text":"\t\tif (strpos($addOnId, '/') !== false)"},{"line":63,"text":"\t\t{"},{"line":64,"text":"\t\t\t$addOnIdParts = explode('/', $addOnId);"},{"line":65,"text":"\t\t\t$vendor = reset($addOnIdParts);"},{"line":66,"text":""},{"line":67,"text":"\t\t\tif (file_exists(\\XF::getAddOnDirectory() . \\XF::$DS . $vendor))"},{"line":68,"text":"\t\t\t{"},{"line":69,"text":"\t\t\t\t$checkPath = \\XF::getAddOnDirectory() . \\XF::$DS . $vendor;"},{"line":70,"text":"\t\t\t}"},{"line":71,"text":""},{"line":72,"text":"\t\t\tif ($addOnDir = opendir(\\XF::getAddOnDirectory()))"},{"line":73,"text":"\t\t\t{"},{"line":74,"text":"\t\t\t\twhile (($dir = readdir($addOnDir)) !== false)"},{"line":75,"text":"\t\t\t\t{"},{"line":76,"text":"\t\t\t\t\tif (strcasecmp($dir, $vendor) == 0 && $dir != $vendor)"},{"line":77,"text":"\t\t\t\t\t{"},{"line":78,"text":"\t\t\t\t\t\t$output->writeln(\"The '{$checkPath}' directory conflicts with an existing directory with the same name but a different case.\");"},{"line":79,"text":"\t\t\t\t\t\treturn 1;"},{"line":80,"text":"\t\t\t\t\t}"},{"line":81,"text":"\t\t\t\t}"},{"line":82,"text":"\t\t\t\tclosedir($addOnDir);"},{"line":83,"text":"\t\t\t}"},{"line":84,"text":"\t\t}"},{"line":85,"text":""},{"line":86,"text":"\t\tif (!is_writable($checkPath))"},{"line":87,"text":"\t\t{"},{"line":88,"text":"\t\t\t$checkPathPrintable = str_replace(\\XF::getRootDirectory() . \\XF::$DS, '', $checkPath);"},{"line":89,"text":"\t\t\t$output->writeln(\"The '{$checkPathPrintable}' directory is not writable.\");"},{"line":90,"text":"\t\t\treturn 1;"},{"line":91,"text":"\t\t}"},{"line":92,"text":""},{"line":93,"text":"\t\t$addOnObj = new AddOn($addOnId, \\XF::app()->addOnManager());"},{"line":94,"text":""},{"line":95,"text":"\t\t$jsonPath = $addOnObj->getJsonPath();"},{"line":96,"text":""},{"line":97,"text":"\t\tif (file_exists($jsonPath))"},{"line":98,"text":"\t\t{"},{"line":99,"text":"\t\t\t$output->writeln(\"The addon.json file already exists at {$jsonPath}. You can create the add-on by installing it from the Admin CP.\");"},{"line":100,"text":"\t\t\treturn 1;"},{"line":101,"text":"\t\t}"},{"line":102,"text":""},{"line":103,"text":"\t\t$question = new Question(\"Enter a title: \");"},{"line":104,"text":"\t\t$question->setValidator($this->getAddOnQuestionFieldValidator('title'));"},{"line":105,"text":"\t\t$title = $helper->ask($input, $output, $question);"},{"line":106,"text":"\t\t$output->writeln(\"\");"},{"line":107,"text":""},{"line":108,"text":"\t\t$question = new Question(\"Enter a version ID. This integer will be used for internal version comparisons. Each release of your add-on should increase this number: \");"},{"line":109,"text":"\t\t$question->setValidator(function ($value)"},{"line":110,"text":"\t\t{"},{"line":111,"text":"\t\t\tif (!preg_match('/^[0-9]+$/', $value))"},{"line":112,"text":"\t\t\t{"},{"line":113,"text":"\t\t\t\tthrow new \\InvalidArgumentException(\"The version ID should contain numeric values only.\");"},{"line":114,"text":"\t\t\t}"},{"line":115,"text":"\t\t\treturn $value;"},{"line":170,"text":""},{"line":171,"text":"\t\t$output->writeln(\"\");"},{"line":172,"text":""},{"line":173,"text":"\t\t$addOn->preSave();"},{"line":174,"text":"\t\tif ($errors = $addOn->getErrors())"},{"line":175,"text":"\t\t{"},{"line":176,"text":"\t\t\t$output->writeln(\"An unexpected error occurred while saving the add-on: \" . reset($errors) . \"\");"},{"line":177,"text":"\t\t\treturn 1;"},{"line":178,"text":"\t\t}"},{"line":179,"text":""},{"line":180,"text":"\t\t$addOn->save();"},{"line":181,"text":""},{"line":182,"text":"\t\tFile::createDirectory($addOnObj->getAddOnDirectory(), false);"},{"line":183,"text":""},{"line":184,"text":"\t\t$json = ["},{"line":185,"text":"\t\t\t'title' => $addOn->title,"},{"line":186,"text":"\t\t\t'version_string' => $addOn->version_string,"},{"line":187,"text":"\t\t\t'version_id' => intval($addOn->version_id),"},{"line":188,"text":"\t\t];"},{"line":189,"text":"\t\tif ($legacyAddOnId)"},{"line":190,"text":"\t\t{"},{"line":191,"text":"\t\t\t$json['legacy_addon_id'] = $legacyAddOnId;"},{"line":192,"text":"\t\t}"},{"line":220,"text":"\t\t\t\t$setupContent = <<< SETUP"}],"sha256":"4ff8f77caa12327158b9a6ba6ed2ffe85b959011279be5a70a8b3e77f75204f5"},{"file":"src/XF/Cli/Command/AddOn/UninstallStep.php","matches":[{"line":1,"text":"addArgument("},{"line":17,"text":"\t\t\t'step',"},{"line":18,"text":"\t\t\tInputArgument::REQUIRED,"},{"line":19,"text":"\t\t\t'The step number to run.'"},{"line":20,"text":"\t\t);"},{"line":21,"text":"\t}"},{"line":22,"text":"}"}],"sha256":"d69b287acd3ea5c02bf23492e1bdef465fb75f22f00b45acdb4ffafe547260e5"},{"file":"src/XF/AddOn/AbstractSetup.php","matches":[{"line":32,"text":"\tabstract public function upgrade(array $stepParams = []);"},{"line":33,"text":""},{"line":34,"text":"\t/**"},{"line":35,"text":"\t * @param array $stepParams"},{"line":36,"text":"\t *"},{"line":37,"text":"\t * @return null|StepResult"},{"line":38,"text":"\t */"},{"line":39,"text":"\tabstract public function uninstall(array $stepParams = []);"},{"line":40,"text":""},{"line":41,"text":"\tpublic function __construct(AddOn $addOn, App $app)"},{"line":42,"text":"\t{"},{"line":43,"text":"\t\t$this->addOn = $addOn;"},{"line":44,"text":"\t\t$this->app = $app;"},{"line":45,"text":"\t}"},{"line":46,"text":""},{"line":47,"text":"\t/**"},{"line":48,"text":"\t * Perform additional requirement checks."},{"line":49,"text":"\t *"},{"line":50,"text":"\t * @param list $errors Errors will block the setup from continuing"},{"line":51,"text":"\t * @param list $warnings Warnings will be displayed but allow the user to continue setup"},{"line":52,"text":"\t *"},{"line":53,"text":"\t * @return void"},{"line":54,"text":"\t */"},{"line":86,"text":"\t\t$this->app->jobManager()->enqueueUnique($uniqueId, FileCleanUp::class, ["},{"line":87,"text":"\t\t\t'addon_id' => $addOn->addon_id,"},{"line":88,"text":"\t\t], false);"},{"line":89,"text":"\t}"},{"line":90,"text":""},{"line":91,"text":"\tpublic function prepareForAction($action)"},{"line":92,"text":"\t{"},{"line":93,"text":"\t\tif ($action == 'uninstall')"},{"line":94,"text":"\t\t{"},{"line":95,"text":"\t\t\t\\XF::db()->ignoreLegacyTableWriteError(true);"},{"line":96,"text":"\t\t}"},{"line":97,"text":"\t}"},{"line":98,"text":""},{"line":99,"text":"\t/**"},{"line":100,"text":"\t * @param $sql"},{"line":101,"text":"\t * @param array $bind"},{"line":102,"text":"\t * @param bool $suppressAll"},{"line":103,"text":"\t *"},{"line":104,"text":"\t * @return bool|AbstractStatement"},{"line":105,"text":"\t * @throws Exception"},{"line":106,"text":"\t */"},{"line":107,"text":"\tprotected function query($sql, $bind = [], $suppressAll = false)"},{"line":108,"text":"\t{"}],"sha256":"6bdd3fe834e15b963a52c9357f54262f2d12f3c7c3686fc31333b549cddf2d88"},{"file":"src/XF/AddOn/AddOn.php","matches":[{"line":332,"text":"\t\t\t\t}"},{"line":333,"text":"\t\t\t}"},{"line":334,"text":"\t\t}"},{"line":335,"text":""},{"line":336,"text":"\t\treturn $this->setup;"},{"line":337,"text":"\t}"},{"line":338,"text":""},{"line":339,"text":"\tpublic function isInstalled()"},{"line":340,"text":"\t{"},{"line":341,"text":"\t\tif ($this->installedAddOn === null)"},{"line":342,"text":"\t\t{"},{"line":343,"text":"\t\t\treturn false;"},{"line":344,"text":"\t\t}"},{"line":345,"text":""},{"line":346,"text":"\t\t$lastAction = $this->installedAddOn->getLastActionStep('install');"},{"line":347,"text":"\t\tif ($lastAction !== null)"},{"line":348,"text":"\t\t{"},{"line":349,"text":"\t\t\t// we haven't completed the install steps yet, don't consider as installed"},{"line":350,"text":"\t\t\treturn false;"},{"line":351,"text":"\t\t}"},{"line":352,"text":""},{"line":353,"text":"\t\treturn true;"},{"line":354,"text":"\t}"},{"line":355,"text":""},{"line":356,"text":"\tpublic function isActive()"},{"line":357,"text":"\t{"},{"line":358,"text":"\t\treturn $this->isInstalled()"},{"line":359,"text":"\t\t\t&& $this->installedAddOn->active;"},{"line":360,"text":"\t}"},{"line":361,"text":""},{"line":362,"text":"\tpublic function isLegacy()"},{"line":363,"text":"\t{"},{"line":364,"text":"\t\treturn $this->isInstalled()"},{"line":365,"text":"\t\t\t&& $this->installedAddOn->is_legacy;"},{"line":366,"text":"\t}"},{"line":367,"text":""},{"line":368,"text":"\tpublic function isDevOutputAvailable()"},{"line":369,"text":"\t{"},{"line":370,"text":"\t\treturn \\XF::app()->developmentOutput()->isAddOnOutputAvailable($this->getAddOnId());"},{"line":371,"text":"\t}"},{"line":372,"text":""},{"line":373,"text":"\tpublic function hasMissingFiles()"},{"line":374,"text":"\t{"},{"line":375,"text":"\t\treturn count($this->missingFiles) > 0;"},{"line":376,"text":"\t}"},{"line":377,"text":""},{"line":378,"text":"\tpublic function hasPendingChanges()"},{"line":379,"text":"\t{"},{"line":380,"text":"\t\treturn $this->isInstalled()"},{"line":381,"text":"\t\t\t&& !$this->isLegacy()"},{"line":382,"text":"\t\t\t&& ("},{"line":383,"text":"\t\t\t\t!$this->isFileVersionValid()"},{"line":384,"text":"\t\t\t\t|| $this->isJsonHashChanged()"},{"line":385,"text":"\t\t\t);"},{"line":386,"text":"\t}"},{"line":387,"text":""},{"line":388,"text":"\tpublic function hasFaIcon()"},{"line":389,"text":"\t{"},{"line":390,"text":"\t\treturn ("},{"line":391,"text":"\t\t\t$this->icon"},{"line":392,"text":"\t\t\t&& !$this->hasIcon()"},{"line":393,"text":"\t\t\t&& preg_match('#^(fa-|fa[a-z] )#', $this->icon)"},{"line":394,"text":"\t\t);"},{"line":395,"text":"\t}"},{"line":431,"text":"\tpublic function isAvailable()"},{"line":432,"text":"\t{"},{"line":433,"text":"\t\treturn count($this->missingFiles) == 0;"},{"line":434,"text":"\t}"},{"line":435,"text":""},{"line":436,"text":"\tpublic function isFileVersionValid()"},{"line":437,"text":"\t{"},{"line":438,"text":"\t\treturn $this->isInstalled()"},{"line":439,"text":"\t\t\t&& $this->isAvailable()"},{"line":440,"text":"\t\t\t&& $this->installedAddOn->version_id == $this->json['version_id'];"},{"line":441,"text":"\t}"},{"line":442,"text":""},{"line":443,"text":"\tpublic function isJsonHashChanged()"},{"line":444,"text":"\t{"},{"line":445,"text":"\t\treturn ("},{"line":446,"text":"\t\t\t$this->isAvailable()"},{"line":447,"text":"\t\t\t&& $this->getJsonHash() !== $this->installedAddOn->json_hash"},{"line":448,"text":"\t\t);"},{"line":449,"text":"\t}"},{"line":450,"text":""},{"line":451,"text":"\tpublic function isJsonVersionNewer()"},{"line":452,"text":"\t{"},{"line":453,"text":"\t\treturn ($this->json['version_id'] > $this->installedAddOn->version_id);"},{"line":459,"text":"\t\t\t'version_id' => $this->json['version_id'],"},{"line":460,"text":"\t\t\t'version_string' => $this->json['version_string'],"},{"line":461,"text":"\t\t];"},{"line":462,"text":"\t}"},{"line":463,"text":""},{"line":464,"text":"\tpublic function canUpgrade()"},{"line":465,"text":"\t{"},{"line":466,"text":"\t\treturn $this->isInstalled()"},{"line":467,"text":"\t\t\t&& $this->isJsonHashChanged()"},{"line":468,"text":"\t\t\t&& $this->isJsonVersionNewer()"},{"line":469,"text":"\t\t\t&& $this->canEdit();"},{"line":470,"text":"\t}"},{"line":471,"text":""}],"sha256":"0e0346a046fff6bde9850cb53e9dc0d0b5379387029dc16925e562fa141ab422"},{"file":"src/XF/AddOn/DataManager.php","matches":[{"line":28,"text":"use XF\\AddOn\\DataType\\StylePropertyGroup;"},{"line":29,"text":"use XF\\AddOn\\DataType\\Template;"},{"line":30,"text":"use XF\\AddOn\\DataType\\TemplateModification;"},{"line":31,"text":"use XF\\AddOn\\DataType\\WidgetDefinition;"},{"line":32,"text":"use XF\\AddOn\\DataType\\WidgetPosition;"},{"line":33,"text":"use XF\\Finder\\AddOnFinder;"},{"line":34,"text":"use XF\\Job\\AddOnData;"},{"line":35,"text":"use XF\\Job\\AddOnUninstallData;"},{"line":36,"text":"use XF\\Job\\Atomic;"},{"line":37,"text":"use XF\\Mvc\\Entity\\Manager;"},{"line":38,"text":"use XF\\Repository\\ClassExtensionRepository;"},{"line":39,"text":"use XF\\Repository\\CodeEventListenerRepository;"},{"line":40,"text":"use XF\\Repository\\ForumTypeRepository;"},{"line":41,"text":"use XF\\Repository\\PaymentRepository;"},{"line":42,"text":"use XF\\Repository\\RouteRepository;"},{"line":43,"text":"use XF\\Repository\\ThreadTypeRepository;"},{"line":44,"text":"use XF\\Util\\File;"},{"line":45,"text":""},{"line":46,"text":"class DataManager"},{"line":47,"text":"{"},{"line":48,"text":"\t/**"},{"line":49,"text":"\t * @var Manager"},{"line":50,"text":"\t */"},{"line":132,"text":"\t\t$addOnManager = \\XF::app()->addOnManager();"},{"line":133,"text":""},{"line":134,"text":"\t\t$addOns = $this->em->getFinder(AddOnFinder::class)->where('active', 1)->fetch();"},{"line":135,"text":"\t\tforeach ($addOns AS $addOn)"},{"line":136,"text":"\t\t{"},{"line":137,"text":"\t\t\t$activeAddOns[$addOn->addon_id] = $addOn->version_id;"},{"line":138,"text":""},{"line":139,"text":"\t\t\t$addOnClass = $addOnManager->getById($addOn->addon_id);"},{"line":140,"text":"\t\t\tif ($addOnClass)"},{"line":141,"text":"\t\t\t{"},{"line":142,"text":"\t\t\t\t$addOnId = $addOn->addon_id;"},{"line":143,"text":"\t\t\t\t$autoloadPath = $addOnClass->composer_autoload;"},{"line":144,"text":""},{"line":145,"text":"\t\t\t\tif (!$autoloadPath)"},{"line":146,"text":"\t\t\t\t{"},{"line":147,"text":"\t\t\t\t\tcontinue;"},{"line":148,"text":"\t\t\t\t}"},{"line":149,"text":""},{"line":150,"text":"\t\t\t\t$addOnAutoload = $addOnManager->getAddOnPath($addOnId) . \\XF::$DS . $autoloadPath;"},{"line":151,"text":""},{"line":152,"text":"\t\t\t\tif (!$this->checkComposerAutoloadPath('installed.json', $addOnAutoload))"},{"line":153,"text":"\t\t\t\t{"},{"line":154,"text":"\t\t\t\t\tcontinue;"},{"line":266,"text":"\t\t}"},{"line":267,"text":""},{"line":268,"text":"\t\t$db->commit();"},{"line":269,"text":"\t}"},{"line":270,"text":""},{"line":271,"text":"\tpublic function enqueueRemoveAddOnData($id)"},{"line":272,"text":"\t{"},{"line":273,"text":"\t\treturn \\XF::app()->jobManager()->enqueueUnique($id . 'AddOnUnInstall', AddOnUninstallData::class, ["},{"line":274,"text":"\t\t\t'addon_id' => $id,"},{"line":275,"text":"\t\t]);"},{"line":276,"text":"\t}"},{"line":277,"text":""},{"line":278,"text":"\tpublic function finalizeRemoveAddOnData($addOnId)"},{"line":279,"text":"\t{"},{"line":280,"text":"\t\t$simpleCache = \\XF::app()->simpleCache();"},{"line":281,"text":"\t\t$simpleCache->deleteSet($addOnId);"},{"line":282,"text":""},{"line":283,"text":"\t\t$this->rebuildActiveAddOnCache();"},{"line":284,"text":"\t}"},{"line":285,"text":""},{"line":286,"text":"\t/**"},{"line":287,"text":"\t * @template T of AbstractDataType"},{"line":288,"text":"\t *"}],"sha256":"cfc97d6e825ba983234c86a405bbcf985706575bba6325e253a70c05001338f0"},{"file":"src/XF/AddOn/StepRunnerUninstallTrait.php","matches":[{"line":3,"text":"namespace XF\\AddOn;"},{"line":4,"text":""},{"line":5,"text":"use function is_array;"},{"line":6,"text":""},{"line":7,"text":"/**"},{"line":8,"text":" * @property AddOn $addOn"},{"line":9,"text":" */"},{"line":10,"text":"trait StepRunnerUninstallTrait"},{"line":11,"text":"{"},{"line":12,"text":"\t/**"},{"line":13,"text":"\t * @param array $stepParams"},{"line":14,"text":"\t *"},{"line":15,"text":"\t * @return null|StepResult"},{"line":16,"text":"\t */"},{"line":17,"text":"\tpublic function uninstall(array $stepParams = [])"},{"line":18,"text":"\t{"},{"line":19,"text":"\t\t$stepParams = array_replace(["},{"line":20,"text":"\t\t\t'step' => 0,"},{"line":21,"text":"\t\t], $stepParams);"},{"line":22,"text":""},{"line":23,"text":"\t\t$step = $stepParams['step'];"},{"line":24,"text":"\t\tif (!$step)"},{"line":25,"text":"\t\t{"},{"line":26,"text":"\t\t\t$step = $this->getUninstallResumeStep();"},{"line":27,"text":"\t\t}"},{"line":28,"text":"\t\treturn $this->uninstallStepRunner($step, $stepParams);"},{"line":29,"text":"\t}"},{"line":30,"text":""},{"line":31,"text":"\tprivate function getUninstallResumeStep()"},{"line":32,"text":"\t{"},{"line":33,"text":"\t\t$installedAddOn = $this->addOn->getInstalledAddOn();"},{"line":34,"text":"\t\tif ($installedAddOn)"},{"line":35,"text":"\t\t{"},{"line":36,"text":"\t\t\t$lastActionStep = $installedAddOn->getLastActionStep('uninstall');"},{"line":37,"text":"\t\t\tif ($lastActionStep)"},{"line":38,"text":"\t\t\t{"},{"line":39,"text":"\t\t\t\treturn $lastActionStep + 1; // this is the last completed step, so resume with the next"},{"line":40,"text":"\t\t\t}"},{"line":41,"text":"\t\t}"},{"line":42,"text":""},{"line":43,"text":"\t\treturn 1;"},{"line":44,"text":"\t}"},{"line":45,"text":""},{"line":46,"text":"\t/**"},{"line":47,"text":"\t * @param integer $step"},{"line":48,"text":"\t * @param array $stepParams"},{"line":49,"text":"\t *"},{"line":50,"text":"\t * @return null|StepResult"},{"line":51,"text":"\t */"},{"line":52,"text":"\tprivate function uninstallStepRunner($step, array $stepParams)"},{"line":53,"text":"\t{"},{"line":54,"text":"\t\t$fnPrefix = 'uninstallStep';"},{"line":55,"text":"\t\t$fn = $fnPrefix . $step;"},{"line":56,"text":"\t\tif (!method_exists($this, $fn))"},{"line":57,"text":"\t\t{"},{"line":58,"text":"\t\t\treturn null;"},{"line":59,"text":"\t\t}"},{"line":60,"text":""},{"line":61,"text":"\t\t$result = $this->$fn($stepParams);"},{"line":62,"text":"\t\tif ($result === null || $result === true)"},{"line":63,"text":"\t\t{"},{"line":64,"text":"\t\t\t$result = new StepResult(true);"},{"line":65,"text":"\t\t}"},{"line":66,"text":"\t\telse if (is_array($result))"},{"line":67,"text":"\t\t{"},{"line":68,"text":"\t\t\t$result = new StepResult(false, $result);"},{"line":69,"text":"\t\t}"},{"line":73,"text":"\t\t\tthrow new \\LogicException(\"Must return a StepResult object\");"},{"line":74,"text":"\t\t}"},{"line":75,"text":""},{"line":76,"text":"\t\t$result->step = $step;"},{"line":77,"text":""},{"line":78,"text":"\t\tif ($result->complete)"},{"line":79,"text":"\t\t{"},{"line":80,"text":"\t\t\t$this->addOn->updatePendingAction('uninstall', $result->step);"},{"line":81,"text":""},{"line":82,"text":"\t\t\t$nextStep = $step + 1;"},{"line":83,"text":"\t\t\t$nextFn = $fnPrefix . $nextStep;"},{"line":84,"text":"\t\t\tif (!method_exists($this, $nextFn))"},{"line":85,"text":"\t\t\t{"},{"line":86,"text":"\t\t\t\treturn null;"},{"line":87,"text":"\t\t\t}"},{"line":88,"text":""},{"line":89,"text":"\t\t\t$result = new StepResult(false, [], $nextStep);"},{"line":90,"text":"\t\t}"},{"line":91,"text":""},{"line":92,"text":"\t\treturn $result;"},{"line":93,"text":"\t}"},{"line":94,"text":"}"}],"sha256":"e58a9ab9c30e3cf3c41a0be392e8c5ac37f744578f7b91f76d663139649c49a9"}],"state":{"addon_columns":["addon_id","title","version_string","version_id","json_hash","active","is_legacy","is_processing","last_pending_action"],"addon_object":{"canUninstall":{"exists":true,"public":true,"required":0,"total":0,"value":false},"class":"XF\\AddOn\\AddOn","getAddOnId":{"exists":true,"public":true,"required":0,"total":0,"value":"Gram/Support"},"getInstalledAddOnVersion":{"exists":false},"getInstalledVersion":{"exists":false},"getLastPendingAction":{"exists":false},"getPendingAction":{"exists":false},"getTitle":{"exists":false},"isActive":{"exists":true,"public":true,"required":0,"total":0,"value":false},"isInstalled":{"exists":true,"public":true,"required":0,"total":0,"value":false},"isProcessing":{"exists":false},"present":true},"addon_row":{"active":"1","addon_id":"Gram/Support","is_legacy":"0","is_processing":"1","json_hash":"f3804541014a3dfde3b35323475c5dbcbb72ebb0d0c319d66385e9203628724d","last_pending_action":"install:1","title":"Gram Support","version_id":"1000050","version_string":"1.0.0 Alpha 3 Unified Fix 3"},"board_active":"0","error_max":45,"errors_after_45":0,"manager":{"class":"XF\\AddOn\\Manager","getAllAddOns":{"exists":true,"public":true,"required":0,"total":0,"value":{"Gram/Support":{"object":"XF\\AddOn\\AddOn"},"Newfi/Dogs":{"object":"XF\\AddOn\\AddOn"},"Newfi/Events":{"object":"XF\\AddOn\\AddOn"},"Newfi/Portal":{"object":"XF\\AddOn\\AddOn"},"XFMG":{"object":"XF\\AddOn\\AddOn"},"XFRM":{"object":"XF\\AddOn\\AddOn"}}},"getById":{"exists":true,"public":true,"required":1,"total":1},"getInstalledAddOns":{"exists":true,"public":true,"required":0,"total":0,"value":{"Newfi/Dogs":{"object":"XF\\AddOn\\AddOn"},"Newfi/Events":{"object":"XF\\AddOn\\AddOn"},"Newfi/Portal":{"object":"XF\\AddOn\\AddOn"},"XFMG":{"object":"XF\\AddOn\\AddOn"},"XFRM":{"object":"XF\\AddOn\\AddOn"}}}},"registry":{"type":"object"},"registry_rows":[{"bytes":187,"contains_gram":true,"data_key":"addOns","sha256":"dca4ff8a040ff5651348c60446b8983b7bc1372d3403ee249da526c679c966e4"},{"bytes":6,"contains_gram":false,"data_key":"addOnsComposer","sha256":"35786c7117b4e38d0f169239752ce71158266ae2f6e4aa230fbbb87bd699c0e3"}]},"state_after":{"addon_columns":["addon_id","title","version_string","version_id","json_hash","active","is_legacy","is_processing","last_pending_action"],"addon_object":{"canUninstall":{"exists":true,"public":true,"required":0,"total":0,"value":false},"class":"XF\\AddOn\\AddOn","getAddOnId":{"exists":true,"public":true,"required":0,"total":0,"value":"Gram/Support"},"getInstalledAddOnVersion":{"exists":false},"getInstalledVersion":{"exists":false},"getLastPendingAction":{"exists":false},"getPendingAction":{"exists":false},"getTitle":{"exists":false},"isActive":{"exists":true,"public":true,"required":0,"total":0,"value":false},"isInstalled":{"exists":true,"public":true,"required":0,"total":0,"value":false},"isProcessing":{"exists":false},"present":true},"addon_row":{"active":"1","addon_id":"Gram/Support","is_legacy":"0","is_processing":"1","json_hash":"f3804541014a3dfde3b35323475c5dbcbb72ebb0d0c319d66385e9203628724d","last_pending_action":"install:1","title":"Gram Support","version_id":"1000050","version_string":"1.0.0 Alpha 3 Unified Fix 3"},"board_active":"0","error_max":45,"errors_after_45":0,"manager":{"class":"XF\\AddOn\\Manager","getAllAddOns":{"exists":true,"public":true,"required":0,"total":0,"value":{"Gram/Support":{"object":"XF\\AddOn\\AddOn"},"Newfi/Dogs":{"object":"XF\\AddOn\\AddOn"},"Newfi/Events":{"object":"XF\\AddOn\\AddOn"},"Newfi/Portal":{"object":"XF\\AddOn\\AddOn"},"XFMG":{"object":"XF\\AddOn\\AddOn"},"XFRM":{"object":"XF\\AddOn\\AddOn"}}},"getById":{"exists":true,"public":true,"required":1,"total":1},"getInstalledAddOns":{"exists":true,"public":true,"required":0,"total":0,"value":{"Newfi/Dogs":{"object":"XF\\AddOn\\AddOn"},"Newfi/Events":{"object":"XF\\AddOn\\AddOn"},"Newfi/Portal":{"object":"XF\\AddOn\\AddOn"},"XFMG":{"object":"XF\\AddOn\\AddOn"},"XFRM":{"object":"XF\\AddOn\\AddOn"}}}},"registry":{"type":"object"},"registry_rows":[{"bytes":187,"contains_gram":true,"data_key":"addOns","sha256":"dca4ff8a040ff5651348c60446b8983b7bc1372d3403ee249da526c679c966e4"},{"bytes":6,"contains_gram":false,"data_key":"addOnsComposer","sha256":"35786c7117b4e38d0f169239752ce71158266ae2f6e4aa230fbbb87bd699c0e3"}]},"status":"OK","uninstall_help":{"lines":["Description:","Uninstalls the specified add-on","Usage:","xf:addon-uninstall [options] [--] ","xf-addon:uninstall","Arguments:","id Add-On ID","Options:","-f, --force Skip verifying that the add-on is uninstallable","-h, --help Display help for the given command. When no command is given display help for the list command","-q, --quiet Do not output any message","-V, --version Display this application version","--ansi|--no-ansi Force (or disable --no-ansi) ANSI output","-n, --no-interaction Do not ask any interactive question","-v|vv|vvv, --verbose Increase the verbosity of messages: 1 for normal output, 2 for more verbose output and 3 for debug"],"rc":0,"stderr_sha256":""}} +SUPPORT066_HOLDS=[] +SUPPORT066_DECISION=NARROW_PROCESSING_STATE_CAPTURED +SUPPORT066_MUTATION_SCOPE=NONE_READ_ONLY +HOMELAB_RESULT_CONTRACT={"changes_made":false,"command_id":"SUPPORT-260909-GRAM-XF-PROCESSING-NARROW-066","rollback_restored":null,"rollback_started":false,"status":"OK","version":1} +SUPPORT066_END OUTPUT_END CHAT_OUTPUT_END