public function handleRequest(AphrontRequest $request) { $viewer = $request->getViewer(); $dblob = $request->getURIData('dblob'); $parent = null; $parents = $this->loadParentFragments($dblob); if ($parents === null) { return new Aphront404Response(); } if (count($parents) !== 0) { $parent = idx($parents, count($parents) - 1, null); } $parent_path = ''; if ($parent !== null) { $parent_path = $parent->getPath(); } $parent_path = trim($parent_path, '/'); $fragment = id(new PhragmentFragment()); $error_view = null; if ($request->isFormPost()) { $errors = array(); $v_name = $request->getStr('name'); $v_fileid = $request->getInt('fileID'); $v_viewpolicy = $request->getStr('viewPolicy'); $v_editpolicy = $request->getStr('editPolicy'); if (strpos($v_name, '/') !== false) { $errors[] = pht("The fragment name can not contain '/'."); } $file = id(new PhabricatorFileQuery())->setViewer($viewer)->withIDs(array($v_fileid))->executeOne(); if (!$file) { $errors[] = pht("The specified file doesn't exist."); } if (!count($errors)) { $depth = 1; if ($parent !== null) { $depth = $parent->getDepth() + 1; } PhragmentFragment::createFromFile($viewer, $file, trim($parent_path . '/' . $v_name, '/'), $v_viewpolicy, $v_editpolicy); return id(new AphrontRedirectResponse())->setURI('/phragment/browse/' . trim($parent_path . '/' . $v_name, '/')); } else { $error_view = id(new PHUIInfoView())->setErrors($errors)->setTitle(pht('Errors while creating fragment')); } } $policies = id(new PhabricatorPolicyQuery())->setViewer($viewer)->setObject($fragment)->execute(); $form = id(new AphrontFormView())->setUser($viewer)->appendChild(id(new AphrontFormTextControl())->setLabel(pht('Parent Path'))->setDisabled(true)->setValue('/' . trim($parent_path . '/', '/')))->appendChild(id(new AphrontFormTextControl())->setLabel(pht('Name'))->setName('name'))->appendChild(id(new AphrontFormTextControl())->setLabel(pht('File ID'))->setName('fileID'))->appendChild(id(new AphrontFormPolicyControl())->setUser($viewer)->setName('viewPolicy')->setPolicyObject($fragment)->setPolicies($policies)->setCapability(PhabricatorPolicyCapability::CAN_VIEW))->appendChild(id(new AphrontFormPolicyControl())->setUser($viewer)->setName('editPolicy')->setPolicyObject($fragment)->setPolicies($policies)->setCapability(PhabricatorPolicyCapability::CAN_EDIT))->appendChild(id(new AphrontFormSubmitControl())->setValue(pht('Create Fragment'))->addCancelButton($this->getApplicationURI('browse/' . $parent_path))); $crumbs = $this->buildApplicationCrumbsWithPath($parents); $crumbs->addTextCrumb(pht('Create Fragment')); $box = id(new PHUIObjectBoxView())->setHeaderText(pht('Create Fragment'))->setForm($form); if ($error_view) { $box->setInfoView($error_view); } $title = pht('Create Fragments'); $view = array($this->renderConfigurationWarningIfRequired(), $box); return $this->newPage()->setTitle($title)->setCrumbs($crumbs)->appendChild($view); }
public function execute(HarbormasterBuild $build, HarbormasterBuildTarget $build_target) { $settings = $this->getSettings(); $variables = $build_target->getVariables(); $path = $this->mergeVariables('vsprintf', $settings['path'], $variables); $artifact = $build->loadArtifact($settings['artifact']); $file = $artifact->loadPhabricatorFile(); $fragment = id(new PhragmentFragmentQuery())->setViewer(PhabricatorUser::getOmnipotentUser())->withPaths(array($path))->executeOne(); if ($fragment === null) { PhragmentFragment::createFromFile(PhabricatorUser::getOmnipotentUser(), $file, $path, PhabricatorPolicies::getMostOpenPolicy(), PhabricatorPolicies::POLICY_USER); } else { if ($file->getMimeType() === 'application/zip') { $fragment->updateFromZIP(PhabricatorUser::getOmnipotentUser(), $file); } else { $fragment->updateFromFile(PhabricatorUser::getOmnipotentUser(), $file); } } }
/** * Apply the specified ZIP archive onto the fragment, removing * and creating fragments as needed. */ public function updateFromZIP(PhabricatorUser $viewer, PhabricatorFile $file) { if ($file->getMimeType() !== 'application/zip') { throw new Exception("File must have mimetype 'application/zip'"); } // First apply the ZIP as normal. $this->updateFromFile($viewer, $file); // Ensure we have ZIP support. $zip = null; try { $zip = new ZipArchive(); } catch (Exception $e) { // The server doesn't have php5-zip, so we can't do recursive updates. return; } $temp = new TempFile(); Filesystem::writeFile($temp, $file->loadFileData()); if (!$zip->open($temp)) { throw new Exception('Unable to open ZIP'); } // Get all of the paths and their data from the ZIP. $mappings = array(); for ($i = 0; $i < $zip->numFiles; $i++) { $path = trim($zip->getNameIndex($i), '/'); $stream = $zip->getStream($path); $data = null; // If the stream is false, then it is a directory entry. We leave // $data set to null for directories so we know not to create a // version entry for them. if ($stream !== false) { $data = stream_get_contents($stream); fclose($stream); } $mappings[$path] = $data; } // We need to detect any directories that are in the ZIP folder that // aren't explicitly noted in the ZIP. This can happen if the file // entries in the ZIP look like: // // * something/blah.png // * something/other.png // * test.png // // Where there is no explicit "something/" entry. foreach ($mappings as $path_key => $data) { if ($data === null) { continue; } $directory = dirname($path_key); while ($directory !== '.') { if (!array_key_exists($directory, $mappings)) { $mappings[$directory] = null; } if (dirname($directory) === $directory) { // dirname() will not reduce this directory any further; to // prevent infinite loop we just break out here. break; } $directory = dirname($directory); } } // Adjust the paths relative to this fragment so we can look existing // fragments up in the DB. $base_path = $this->getPath(); $paths = array(); foreach ($mappings as $p => $data) { $paths[] = $base_path . '/' . $p; } // FIXME: What happens when a child exists, but the current user // can't see it. We're going to create a new child with the exact // same path and then bad things will happen. $children = id(new PhragmentFragmentQuery())->setViewer($viewer)->needLatestVersion(true)->withLeadingPath($this->getPath() . '/')->execute(); $children = mpull($children, null, 'getPath'); // Iterate over the existing fragments. foreach ($children as $full_path => $child) { $path = substr($full_path, strlen($base_path) + 1); if (array_key_exists($path, $mappings)) { if ($child->isDirectory() && $mappings[$path] === null) { // Don't create a version entry for a directory // (unless it's been converted into a file). continue; } // The file is being updated. $file = PhabricatorFile::newFromFileData($mappings[$path], array('name' => basename($path))); $child->updateFromFile($viewer, $file); } else { // The file is being deleted. $child->deleteFile($viewer); } } // Iterate over the mappings to find new files. foreach ($mappings as $path => $data) { if (!array_key_exists($base_path . '/' . $path, $children)) { // The file is being created. If the data is null, // then this is explicitly a directory being created. $file = null; if ($mappings[$path] !== null) { $file = PhabricatorFile::newFromFileData($mappings[$path], array('name' => basename($path))); } PhragmentFragment::createFromFile($viewer, $file, $base_path . '/' . $path, $this->getViewPolicy(), $this->getEditPolicy()); } } }