break;
case 'optionalPackages':
- $step = $this->selectOptionalPackages($nodeData);
+ $step = $this->selectOptionalPackages($node, $nodeData);
break;
default:
}
if ($step->splitNode()) {
- $this->nodeBuilder->insertNode($node, $data['sequenceNo']);
+ $this->nodeBuilder->cloneNode($node, $data['sequenceNo']);
break;
}
}
return $installationStep;
}
- protected function selectOptionalPackages(array $nodeData) {
+ protected function selectOptionalPackages($currentNode, array $nodeData) {
$installationStep = new PackageInstallationStep();
$document = $this->promptOptionalPackages($nodeData);
if ($document !== null && $document instanceof form\FormDocument) {
$installationStep->setDocument($document);
+ $installationStep->setSplitNode();
+ }
+ // insert new nodes for each package
+ else if (is_array($document)) {
+ // get target child node
+ $node = $currentNode;
+ $queue = $this->queue;
+ $shiftNodes = false;
+
+ foreach ($nodeData as $package) {
+ if (in_array($package['package'], $document)) {
+ if (!$shiftNodes) {
+ $this->nodeBuilder->shiftNodes($currentNode, 'tempNode');
+ $shiftNodes = true;
+ }
+
+ $queue = PackageInstallationQueueEditor::create(array(
+ 'parentQueueID' => $queue->queueID,
+ 'processNo' => $this->queue->processNo,
+ 'userID' => WCF::getUser()->userID,
+ 'package' => $package['package'],
+ 'packageName' => $package['packageName'],
+ 'archive' => $package['archive'],
+ 'action' => $queue->action
+ ));
+
+ $installation = new PackageInstallationDispatcher($queue);
+ $installation->nodeBuilder->setParentNode($node);
+ $installation->nodeBuilder->buildNodes();
+ $node = $installation->nodeBuilder->getCurrentNode();
+ }
+ }
+
+ // shift nodes
+ if ($shiftNodes) {
+ $this->nodeBuilder->shiftNodes('tempNode', $node);
+ }
}
-
- $installationStep->setSplitNode();
return $installationStep;
}
$document = PackageInstallationFormManager::getForm($this->queue, 'optionalPackages');
$document->handleRequest();
- $packages = $document->getValue('optionalPackages');
- if (!empty($packages)) {
- foreach ($packages as $package) {
- // haha, this is going to be mad
-
- }
- }
- die('<pre>'.print_r($packages, true));
+ return $document->getValue('optionalPackages');
}
}
* @param string $node
* @param integer $sequenceNo
*/
- public function insertNode($node, $sequenceNo) {
+ public function cloneNode($node, $sequenceNo) {
$newNode = $this->getToken();
// update descendants
));
}
+ /**
+ * Inserts a node before given target node. Will shift all target
+ * nodes to provide to be descendants of the new node. If you intend
+ * to insert more than a single node, you should prefer shiftNodes().
+ *
+ * @param string $beforeNode
+ * @param function $callback
+ */
+ public function insertNode($beforeNode, $callback) {
+ // verify if callback is a valid function
+ if (!is_callable($callback)) {
+ throw new SystemException("Provided callback is not a callable function.");
+ }
+
+ $newNode = $this->getToken();
+
+ // update descendants
+ $sql = "UPDATE wcf".WCF_N."_package_installation_node
+ SET parentNode = ?
+ WHERE parentNode = ?
+ AND processNo = ?";
+ $statement = WCF::getDB()->prepareStatement($sql);
+ $statement->execute(array(
+ $newNode,
+ $beforeNode,
+ $this->installation->queue->processNo
+ ));
+
+ // execute callback
+ $callback($beforeNode, $newNode);
+ }
+
+ /**
+ * Shifts nodes to allow dynamic inserts at runtime.
+ *
+ * @param string $oldParentNode
+ * @param string $newParentNode
+ */
+ public function shiftNodes($oldParentNode, $newParentNode) {
+ $sql = "UPDATE wcf".WCF_N."_package_installation_node
+ SET parentNode = ?
+ WHERE parentNode = ?
+ AND processNo = ?";
+ $statement = WCF::getDB()->prepareStatement($sql);
+ $statement->execute(array(
+ $newParentNode,
+ $oldParentNode,
+ $this->installation->queue->processNo
+ ));
+ }
+
/**
* Builds package node used to install the package itself.
*/
sequenceNo SMALLINT(4) NOT NULL DEFAULT 0,
node CHAR(8) NOT NULL DEFAULT '',
parentNode CHAR(8) NOT NULL DEFAULT '',
- nodeType ENUM('package', 'pip') NOT NULL DEFAULT 'package',
+ nodeType ENUM('optionalPackages','package', 'pip') NOT NULL DEFAULT 'package',
nodeData TEXT NOT NULL,
done TINYINT(1) NOT NULL DEFAULT 0
);