コード例 #1
0
 protected function execute(ConduitAPIRequest $request)
 {
     $viewer = $request->getUser();
     $file_phid = $request->getValue('filePHID');
     $file = $this->loadFileByPHID($viewer, $file_phid);
     $start = $request->getValue('byteStart');
     $data = $request->getValue('data');
     $encoding = $request->getValue('dataEncoding');
     switch ($encoding) {
         case 'base64':
             $data = $this->decodeBase64($data);
             break;
         case null:
             break;
         default:
             throw new Exception(pht('Unsupported data encoding.'));
     }
     $length = strlen($data);
     $chunk = $this->loadFileChunkForUpload($viewer, $file, $start, $start + $length);
     // NOTE: These files have a view policy which prevents normal access. They
     // are only accessed through the storage engine.
     $chunk_data = PhabricatorFile::newFromFileData($data, array('name' => $file->getMonogram() . '.chunk-' . $chunk->getID(), 'viewPolicy' => PhabricatorPolicies::POLICY_NOONE));
     $chunk->setDataFilePHID($chunk_data->getPHID())->save();
     $missing = $this->loadAnyMissingChunk($viewer, $file);
     if (!$missing) {
         $file->setIsPartial(0)->save();
     }
     return null;
 }
コード例 #2
0
 public function saveFile($path, $name)
 {
     $data = $this->readFile($path);
     $file = PhabricatorFile::newFromFileData($data, array('name' => $name));
     $file->setName($name);
     $file->save();
     return $file;
 }
コード例 #3
0
 protected function execute(ConduitAPIRequest $request)
 {
     $data = $request->getValue('data_base64');
     $name = $request->getValue('name');
     $data = base64_decode($data, $strict = true);
     $user = $request->getUser();
     $file = PhabricatorFile::newFromFileData($data, array('name' => $name, 'authorPHID' => $user->getPHID()));
     return $file->getPHID();
 }
コード例 #4
0
 private function generateTestFile(PhabricatorUser $actor)
 {
     $engine = new PhabricatorTestStorageEngine();
     $data = Filesystem::readRandomCharacters(64);
     $params = array('name' => 'test.' . $actor->getPHID(), 'viewPolicy' => $actor->getPHID(), 'authorPHID' => $actor->getPHID(), 'storageEngines' => array($engine));
     $file = PhabricatorFile::newFromFileData($data, $params);
     $file->save();
     return $file;
 }
コード例 #5
0
 public function generate()
 {
     $author_phid = $this->loadPhabrictorUserPHID();
     $dimension = 1 << rand(5, 12);
     $image = id(new PhabricatorLipsumMondrianArtist())->generate($dimension, $dimension);
     $file = PhabricatorFile::newFromFileData($image, array('name' => 'rand-' . rand(1000, 9999)));
     $file->setAuthorPHID($author_phid);
     $file->setMimeType('image/jpeg');
     return $file->save();
 }
 public function processRequest()
 {
     $request = $this->getRequest();
     $user = $request->getUser();
     $data = file_get_contents('php://input');
     $name = $request->getStr('name');
     $file = PhabricatorFile::newFromFileData($data, array('name' => $request->getStr('name'), 'authorPHID' => $user->getPHID()));
     $view = new AphrontAttachedFileView();
     $view->setFile($file);
     return id(new AphrontAjaxResponse())->setContent(array('id' => $file->getID(), 'phid' => $file->getPHID(), 'html' => $view->render(), 'uri' => $file->getBestURI()));
 }
コード例 #7
0
 protected function execute(ConduitAPIRequest $request)
 {
     $viewer = $request->getUser();
     $name = $request->getValue('name');
     $can_cdn = $request->getValue('canCDN');
     $view_policy = $request->getValue('viewPolicy');
     $data = $request->getValue('data_base64');
     $data = $this->decodeBase64($data);
     $file = PhabricatorFile::newFromFileData($data, array('name' => $name, 'authorPHID' => $viewer->getPHID(), 'viewPolicy' => $view_policy, 'canCDN' => $can_cdn, 'isExplicitUpload' => true));
     return $file->getPHID();
 }
コード例 #8
0
 public function handleRequest(AphrontRequest $request)
 {
     $viewer = $request->getViewer();
     $color_map = PhabricatorFilesComposeIconBuiltinFile::getAllColors();
     $icon_map = $this->getIconMap();
     if ($request->isFormPost()) {
         $project_phid = $request->getStr('projectPHID');
         if ($project_phid) {
             $project = id(new PhabricatorProjectQuery())->setViewer($viewer)->withPHIDs(array($project_phid))->requireCapabilities(array(PhabricatorPolicyCapability::CAN_VIEW, PhabricatorPolicyCapability::CAN_EDIT))->executeOne();
             if (!$project) {
                 return new Aphront404Response();
             }
         }
         $icon = $request->getStr('icon');
         $color = $request->getStr('color');
         $composer = id(new PhabricatorFilesComposeIconBuiltinFile())->setIcon($icon)->setColor($color);
         $data = $composer->loadBuiltinFileData();
         $file = PhabricatorFile::newFromFileData($data, array('name' => $composer->getBuiltinDisplayName(), 'profile' => true, 'canCDN' => true));
         if ($project_phid) {
             $edit_uri = '/project/manage/' . $project->getID() . '/';
             $xactions = array();
             $xactions[] = id(new PhabricatorProjectTransaction())->setTransactionType(PhabricatorProjectTransaction::TYPE_IMAGE)->setNewValue($file->getPHID());
             $editor = id(new PhabricatorProjectTransactionEditor())->setActor($viewer)->setContentSourceFromRequest($request)->setContinueOnMissingFields(true)->setContinueOnNoEffect(true);
             $editor->applyTransactions($project, $xactions);
             return id(new AphrontRedirectResponse())->setURI($edit_uri);
         } else {
             $content = array('phid' => $file->getPHID());
             return id(new AphrontAjaxResponse())->setContent($content);
         }
     }
     $value_color = head_key($color_map);
     $value_icon = head_key($icon_map);
     require_celerity_resource('people-profile-css');
     $buttons = array();
     foreach ($color_map as $color => $info) {
         $quip = idx($info, 'quip');
         $buttons[] = javelin_tag('button', array('class' => 'grey profile-image-button', 'sigil' => 'has-tooltip compose-select-color', 'style' => 'margin: 0 8px 8px 0', 'meta' => array('color' => $color, 'tip' => $quip)), id(new PHUIIconView())->addClass('compose-background-' . $color));
     }
     $icons = array();
     foreach ($icon_map as $icon => $spec) {
         $quip = idx($spec, 'quip');
         $icons[] = javelin_tag('button', array('class' => 'grey profile-image-button', 'sigil' => 'has-tooltip compose-select-icon', 'style' => 'margin: 0 8px 8px 0', 'meta' => array('icon' => $icon, 'tip' => $quip)), id(new PHUIIconView())->setIcon($icon)->addClass('compose-icon-bg'));
     }
     $dialog_id = celerity_generate_unique_node_id();
     $color_input_id = celerity_generate_unique_node_id();
     $icon_input_id = celerity_generate_unique_node_id();
     $preview_id = celerity_generate_unique_node_id();
     $preview = id(new PHUIIconView())->setID($preview_id)->addClass('compose-background-' . $value_color)->setIcon($value_icon)->addClass('compose-icon-bg');
     $color_input = javelin_tag('input', array('type' => 'hidden', 'name' => 'color', 'value' => $value_color, 'id' => $color_input_id));
     $icon_input = javelin_tag('input', array('type' => 'hidden', 'name' => 'icon', 'value' => $value_icon, 'id' => $icon_input_id));
     Javelin::initBehavior('phabricator-tooltips');
     Javelin::initBehavior('icon-composer', array('dialogID' => $dialog_id, 'colorInputID' => $color_input_id, 'iconInputID' => $icon_input_id, 'previewID' => $preview_id, 'defaultColor' => $value_color, 'defaultIcon' => $value_icon));
     return $this->newDialog()->setFormID($dialog_id)->setClass('compose-dialog')->setTitle(pht('Compose Image'))->appendChild(phutil_tag('div', array('class' => 'compose-header'), pht('Choose Background Color')))->appendChild($buttons)->appendChild(phutil_tag('div', array('class' => 'compose-header'), pht('Choose Icon')))->appendChild($icons)->appendChild(phutil_tag('div', array('class' => 'compose-header'), pht('Preview')))->appendChild($preview)->appendChild($color_input)->appendChild($icon_input)->addCancelButton('/')->addSubmitButton(pht('Save Image'));
 }
コード例 #9
0
 public function generate()
 {
     $authorphid = $this->loadPhabrictorUserPHID();
     $language = $this->generateLanguage();
     $content = $this->generateContent($language);
     $title = $this->generateTitle($language);
     $paste_file = PhabricatorFile::newFromFileData($content, array('name' => $title, 'mime-type' => 'text/plain; charset=utf-8', 'authorPHID' => $authorphid));
     $policy = $this->generatePolicy();
     $filephid = $paste_file->getPHID();
     $parentphid = $this->loadPhabrictorPastePHID();
     $paste = id(new PhabricatorPaste())->setParentPHID($parentphid)->setAuthorPHID($authorphid)->setTitle($title)->setLanguage($language)->setViewPolicy($policy)->setFilePHID($filephid)->save();
     return $paste;
 }
コード例 #10
0
 protected function execute(ConduitAPIRequest $request)
 {
     $data = $request->getValue('data_base64');
     $name = $request->getValue('name');
     $can_cdn = $request->getValue('canCDN');
     $view_policy = $request->getValue('viewPolicy');
     $user = $request->getUser();
     $data = base64_decode($data, $strict = true);
     if (!$view_policy) {
         $view_policy = PhabricatorPolicies::getMostOpenPolicy();
     }
     $file = PhabricatorFile::newFromFileData($data, array('name' => $name, 'authorPHID' => $user->getPHID(), 'viewPolicy' => $view_policy, 'canCDN' => $can_cdn, 'isExplicitUpload' => true));
     return $file->getPHID();
 }
コード例 #11
0
 protected function execute(ConduitAPIRequest $request)
 {
     $content = $request->getValue('content');
     $title = $request->getValue('title');
     $language = $request->getValue('language');
     if (!strlen($content)) {
         throw new ConduitException('ERR-NO-PASTE');
     }
     $title = nonempty($title, 'Masterwork From Distant Lands');
     $language = nonempty($language, '');
     $user = $request->getUser();
     $paste_file = PhabricatorFile::newFromFileData($content, array('name' => $title, 'mime-type' => 'text/plain; charset=utf-8', 'authorPHID' => $user->getPHID()));
     $paste = new PhabricatorPaste();
     $paste->setTitle($title);
     $paste->setLanguage($language);
     $paste->setFilePHID($paste_file->getPHID());
     $paste->setAuthorPHID($user->getPHID());
     $paste->save();
     return $this->buildPasteInfoDictionary($paste);
 }
コード例 #12
0
 public function testAES256Storage()
 {
     $engine = new PhabricatorTestStorageEngine();
     $key_name = 'test.abcd';
     $key_text = 'abcdefghijklmnopABCDEFGHIJKLMNOP';
     PhabricatorKeyring::addKey(array('name' => $key_name, 'type' => 'aes-256-cbc', 'material.base64' => base64_encode($key_text)));
     $format = id(new PhabricatorFileAES256StorageFormat())->selectMasterKey($key_name);
     $data = 'The cow jumped over the full moon.';
     $params = array('name' => 'test.dat', 'storageEngines' => array($engine), 'format' => $format);
     $file = PhabricatorFile::newFromFileData($data, $params);
     // We should have a file stored as AES256.
     $format_key = $format->getStorageFormatKey();
     $this->assertEqual($format_key, $file->getStorageFormat());
     $this->assertEqual($data, $file->loadFileData());
     // The actual raw data in the storage engine should be encrypted. We
     // can't really test this, but we can make sure it's not the same as the
     // input data.
     $raw_data = $engine->readFile($file->getStorageHandle());
     $this->assertTrue($data !== $raw_data);
 }
コード例 #13
0
 private function processCreateRequest()
 {
     $request = $this->getRequest();
     $user = $request->getUser();
     $fork = $request->getInt('fork');
     $error_view = null;
     $e_text = true;
     $new_paste = new PhabricatorPaste();
     $new_paste_text = null;
     $new_paste_language = PhabricatorEnv::getEnvConfig('pygments.dropdown-default');
     if ($request->isFormPost()) {
         $errors = array();
         $text = $request->getStr('text');
         if (!strlen($text)) {
             $e_text = 'Required';
             $errors[] = 'The paste may not be blank.';
         } else {
             $e_text = null;
         }
         $parent_phid = $request->getStr('parent');
         if ($parent_phid) {
             $parent = id(new PhabricatorPaste())->loadOneWhere('phid = %s', $parent_phid);
             if ($parent) {
                 $new_paste->setParentPHID($parent->getPHID());
             }
         }
         $title = $request->getStr('title');
         $new_paste->setTitle($title);
         $new_paste_language = $request->getStr('language');
         if (!$errors) {
             if ($new_paste_language == 'infer') {
                 // If it's infer, store an empty string. Otherwise, store the
                 // language name. We do this so we can refer to 'infer' elsewhere
                 // in the code (such as default value) while retaining backwards
                 // compatibility with old posts with no language stored.
                 $new_paste_language = '';
             }
             $new_paste->setLanguage($new_paste_language);
             $new_paste_file = PhabricatorFile::newFromFileData($text, array('name' => $title, 'mime-type' => 'text/plain; charset=utf-8', 'authorPHID' => $user->getPHID()));
             $new_paste->setFilePHID($new_paste_file->getPHID());
             $new_paste->setAuthorPHID($user->getPHID());
             $new_paste->save();
             return id(new AphrontRedirectResponse())->setURI('/P' . $new_paste->getID());
         } else {
             $error_view = new AphrontErrorView();
             $error_view->setErrors($errors);
             $error_view->setTitle('A problem has occurred!');
         }
     } else {
         if ($fork) {
             $fork_paste = id(new PhabricatorPaste())->load($fork);
             if ($fork_paste) {
                 $new_paste->setTitle('Fork of ' . $fork_paste->getID() . ': ' . $fork_paste->getTitle());
                 $fork_file = id(new PhabricatorFile())->loadOneWhere('phid = %s', $fork_paste->getFilePHID());
                 $new_paste_text = $fork_file->loadFileData();
                 $new_paste_language = nonempty($fork_paste->getLanguage(), 'infer');
                 $new_paste->setParentPHID($fork_paste->getPHID());
             }
         }
     }
     $this->setErrorView($error_view);
     $this->setErrorText($e_text);
     $this->setPasteText($new_paste_text);
     $new_paste->setLanguage($new_paste_language);
     $this->setPaste($new_paste);
 }
コード例 #14
0
 private function setDefaultProfilePicture(PhabricatorProject $project)
 {
     if ($project->isMilestone()) {
         return;
     }
     $compose_color = $project->getDisplayIconComposeColor();
     $compose_icon = $project->getDisplayIconComposeIcon();
     $builtin = id(new PhabricatorFilesComposeIconBuiltinFile())->setColor($compose_color)->setIcon($compose_icon);
     $data = $builtin->loadBuiltinFileData();
     $file = PhabricatorFile::newFromFileData($data, array('name' => $builtin->getBuiltinDisplayName(), 'profile' => true, 'canCDN' => true));
     $project->setProfileImagePHID($file->getPHID())->save();
 }
コード例 #15
0
 public function processRequest()
 {
     $request = $this->getRequest();
     $user = $request->getUser();
     $paste = new PhabricatorPaste();
     $error_view = null;
     $e_text = true;
     $fork = $request->getInt('fork');
     $paste_text = null;
     $paste_parent = null;
     if ($request->isFormPost()) {
         $errors = array();
         $title = $request->getStr('title');
         $paste_language = $request->getStr('language');
         $text = $request->getStr('text');
         if (!strlen($text)) {
             $e_text = 'Required';
             $errors[] = 'The paste may not be blank.';
         } else {
             $e_text = null;
         }
         $parent = id(new PhabricatorPaste())->loadOneWhere('phid = %s', $request->getStr('parent'));
         if ($parent) {
             $paste->setParentPHID($parent->getPHID());
         }
         $paste->setTitle($title);
         if (!$errors) {
             if ($paste_language == 'infer') {
                 // If it's infer, store an empty string. Otherwise, store the
                 // language name. We do this so we can refer to 'infer' elsewhere
                 // in the code (such as default value) while retaining backwards
                 // compatibility with old posts with no language stored.
                 $paste_language = '';
             }
             $paste->setLanguage($paste_language);
             $paste_file = PhabricatorFile::newFromFileData($text, array('name' => $title, 'mime-type' => 'text/plain; charset=utf-8', 'authorPHID' => $user->getPHID()));
             $paste->setFilePHID($paste_file->getPHID());
             $paste->setAuthorPHID($user->getPHID());
             $paste->save();
             return id(new AphrontRedirectResponse())->setURI('/P' . $paste->getID());
         } else {
             $error_view = new AphrontErrorView();
             $error_view->setErrors($errors);
             $error_view->setTitle('A problem has occurred!');
         }
     } else {
         if ($fork) {
             $fork_paste = id(new PhabricatorPaste())->load($fork);
             if ($fork_paste) {
                 $paste->setTitle('Fork of ' . $fork_paste->getID() . ': ' . $fork_paste->getTitle());
                 $fork_file = id(new PhabricatorFile())->loadOneWhere('phid = %s', $fork_paste->getFilePHID());
                 $paste_text = $fork_file->loadFileData();
                 $paste_language = nonempty($fork_paste->getLanguage(), 'infer');
                 $paste_parent = $fork_paste->getPHID();
             }
         } else {
             $paste_language = PhabricatorEnv::getEnvConfig('pygments.dropdown-default');
         }
     }
     $form = new AphrontFormView();
     $available_languages = PhabricatorEnv::getEnvConfig('pygments.dropdown-choices');
     asort($available_languages);
     $language_select = id(new AphrontFormSelectControl())->setLabel('Language')->setName('language')->setValue($paste_language)->setOptions($available_languages);
     $form->setUser($user)->setAction($request->getRequestURI()->getPath())->addHiddenInput('parent', $paste_parent)->appendChild(id(new AphrontFormTextControl())->setLabel('Title')->setValue($paste->getTitle())->setName('title'))->appendChild($language_select)->appendChild(id(new AphrontFormTextAreaControl())->setLabel('Text')->setError($e_text)->setValue($paste_text)->setHeight(AphrontFormTextAreaControl::HEIGHT_VERY_TALL)->setName('text'))->appendChild(id(new AphrontFormSubmitControl())->addCancelButton('/paste/')->setValue('Create Paste'));
     $panel = new AphrontPanelView();
     $panel->setWidth(AphrontPanelView::WIDTH_FORM);
     $panel->setHeader('Create a Paste');
     $panel->appendChild($form);
     return $this->buildStandardPageResponse(array($error_view, $panel), array('title' => 'Paste Creation', 'tab' => 'create'));
 }
コード例 #16
0
 /**
  * Create a new @{class:PhabricatorFile} from raw data.
  *
  * @param string Raw file data.
  */
 protected function newFileFromData($data)
 {
     if ($this->file) {
         $name = $this->file->getName();
     } else {
         $name = 'default.png';
     }
     $defaults = array('canCDN' => true, 'name' => $this->getTransformKey() . '-' . $name);
     $properties = $this->getFileProperties() + $defaults;
     return PhabricatorFile::newFromFileData($data, $properties);
 }
コード例 #17
0
 public function processRequest()
 {
     $request = $this->getRequest();
     $user = $request->getUser();
     $parent = null;
     $parent_id = null;
     if (!$this->id) {
         $is_create = true;
         $paste = new PhabricatorPaste();
         $parent_id = $request->getStr('parent');
         if ($parent_id) {
             // NOTE: If the Paste is forked from a paste which the user no longer
             // has permission to see, we still let them edit it.
             $parent = id(new PhabricatorPasteQuery())->setViewer($user)->withIDs(array($parent_id))->needContent(true)->execute();
             $parent = head($parent);
             if ($parent) {
                 $paste->setParentPHID($parent->getPHID());
             }
         }
         $paste->setAuthorPHID($user->getPHID());
     } else {
         $is_create = false;
         $paste = id(new PhabricatorPasteQuery())->setViewer($user)->requireCapabilities(array(PhabricatorPolicyCapability::CAN_VIEW, PhabricatorPolicyCapability::CAN_EDIT))->withIDs(array($this->id))->executeOne();
         if (!$paste) {
             return new Aphront404Response();
         }
     }
     $text = null;
     $e_text = true;
     $errors = array();
     if ($request->isFormPost()) {
         if ($is_create) {
             $text = $request->getStr('text');
             if (!strlen($text)) {
                 $e_text = 'Required';
                 $errors[] = 'The paste may not be blank.';
             } else {
                 $e_text = null;
             }
         }
         $paste->setTitle($request->getStr('title'));
         $paste->setLanguage($request->getStr('language'));
         if (!$errors) {
             if ($is_create) {
                 $paste_file = PhabricatorFile::newFromFileData($text, array('name' => $paste->getTitle(), 'mime-type' => 'text/plain; charset=utf-8', 'authorPHID' => $user->getPHID()));
                 $paste->setFilePHID($paste_file->getPHID());
             }
             $paste->save();
             return id(new AphrontRedirectResponse())->setURI($paste->getURI());
         }
     } else {
         if ($is_create && $parent) {
             $paste->setTitle('Fork of ' . $parent->getFullName());
             $paste->setLanguage($parent->getLanguage());
             $text = $parent->getContent();
         }
     }
     $error_view = null;
     if ($errors) {
         $error_view = id(new AphrontErrorView())->setTitle('A fatal omission!')->setErrors($errors);
     }
     $form = new AphrontFormView();
     $form->setFlexible(true);
     $langs = array('' => '(Detect With Wizardly Powers)') + PhabricatorEnv::getEnvConfig('pygments.dropdown-choices');
     $form->setUser($user)->addHiddenInput('parent', $parent_id)->appendChild(id(new AphrontFormTextControl())->setLabel('Title')->setValue($paste->getTitle())->setName('title'))->appendChild(id(new AphrontFormSelectControl())->setLabel('Language')->setName('language')->setValue($paste->getLanguage())->setOptions($langs));
     if ($is_create) {
         $form->appendChild(id(new AphrontFormTextAreaControl())->setLabel('Text')->setError($e_text)->setValue($text)->setHeight(AphrontFormTextAreaControl::HEIGHT_VERY_TALL)->setCustomClass('PhabricatorMonospaced')->setName('text'));
     }
     /* TODO: Doesn't have any useful options yet.
          ->appendChild(
            id(new AphrontFormPolicyControl())
              ->setLabel('Visible To')
              ->setUser($user)
              ->setValue(
                $new_paste->getPolicy(PhabricatorPolicyCapability::CAN_VIEW))
              ->setName('policy'))
        */
     $submit = new AphrontFormSubmitControl();
     if (!$is_create) {
         $submit->addCancelButton($paste->getURI());
         $submit->setValue('Save Paste');
         $title = 'Edit ' . $paste->getFullName();
     } else {
         $submit->setValue('Create Paste');
         $title = 'Create Paste';
     }
     $form->appendChild($submit);
     $nav = $this->buildSideNavView();
     $nav->selectFilter('edit');
     $nav->appendChild(array(id(new PhabricatorHeaderView())->setHeader($title), $error_view, $form));
     return $this->buildApplicationPage($nav, array('title' => $title, 'device' => true));
 }
コード例 #18
0
 /**
  * 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(pht("File must have mimetype '%s'.", '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(pht('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)));
             }
             self::createFromFile($viewer, $file, $base_path . '/' . $path, $this->getViewPolicy(), $this->getEditPolicy());
         }
     }
 }
コード例 #19
0
ファイル: add_macro.php プロジェクト: pugong/phabricator
<?php 
$root = dirname(dirname(dirname(__FILE__)));
require_once $root . '/scripts/__init_script__.php';
$args = new PhutilArgumentParser($argv);
$args->setTagline(pht('load files as image macros'));
$args->setSynopsis(<<<EOHELP
**add_macro.php** __image__ [--as __name__]
    Add an image macro. This can be useful for importing a large number
    of macros.
EOHELP
);
$args->parseStandardArguments();
$args->parse(array(array('name' => 'as', 'param' => 'name', 'help' => pht('Use a specific name instead of the first part of the image name.')), array('name' => 'more', 'wildcard' => true)));
$more = $args->getArg('more');
if (count($more) !== 1) {
    $args->printHelpAndExit();
}
$path = head($more);
$data = Filesystem::readFile($path);
$name = $args->getArg('as');
if ($name === null) {
    $name = head(explode('.', basename($path)));
}
$existing = id(new PhabricatorFileImageMacro())->loadOneWhere('name = %s', $name);
if ($existing) {
    throw new Exception(pht("A macro already exists with the name '%s'!", $name));
}
$file = PhabricatorFile::newFromFileData($data, array('name' => basename($path), 'canCDN' => true));
$macro = id(new PhabricatorFileImageMacro())->setFilePHID($file->getPHID())->setName($name)->save();
$id = $file->getID();
echo pht("Added macro '%s' (%s).", $name, "F{$id}") . "\n";
コード例 #20
0
 public function testFileTransformDelete()
 {
     // We want to test that a file deletes all its inbound transformation
     // records and outbound transformed derivatives when it is deleted.
     // First, we create a chain of transforms, A -> B -> C.
     $engine = new PhabricatorTestStorageEngine();
     $params = array('name' => 'test.txt', 'storageEngines' => array($engine));
     $a = PhabricatorFile::newFromFileData('a', $params);
     $b = PhabricatorFile::newFromFileData('b', $params);
     $c = PhabricatorFile::newFromFileData('c', $params);
     id(new PhabricatorTransformedFile())->setOriginalPHID($a->getPHID())->setTransform('test:a->b')->setTransformedPHID($b->getPHID())->save();
     id(new PhabricatorTransformedFile())->setOriginalPHID($b->getPHID())->setTransform('test:b->c')->setTransformedPHID($c->getPHID())->save();
     // Now, verify that A -> B and B -> C exist.
     $xform_a = id(new PhabricatorFileQuery())->setViewer(PhabricatorUser::getOmnipotentUser())->withTransforms(array(array('originalPHID' => $a->getPHID(), 'transform' => true)))->execute();
     $this->assertEqual(1, count($xform_a));
     $this->assertEqual($b->getPHID(), head($xform_a)->getPHID());
     $xform_b = id(new PhabricatorFileQuery())->setViewer(PhabricatorUser::getOmnipotentUser())->withTransforms(array(array('originalPHID' => $b->getPHID(), 'transform' => true)))->execute();
     $this->assertEqual(1, count($xform_b));
     $this->assertEqual($c->getPHID(), head($xform_b)->getPHID());
     // Delete "B".
     $b->delete();
     // Now, verify that the A -> B and B -> C links are gone.
     $xform_a = id(new PhabricatorFileQuery())->setViewer(PhabricatorUser::getOmnipotentUser())->withTransforms(array(array('originalPHID' => $a->getPHID(), 'transform' => true)))->execute();
     $this->assertEqual(0, count($xform_a));
     $xform_b = id(new PhabricatorFileQuery())->setViewer(PhabricatorUser::getOmnipotentUser())->withTransforms(array(array('originalPHID' => $b->getPHID(), 'transform' => true)))->execute();
     $this->assertEqual(0, count($xform_b));
     // Also verify that C has been deleted.
     $alternate_c = id(new PhabricatorFileQuery())->setViewer(PhabricatorUser::getOmnipotentUser())->withPHIDs(array($c->getPHID()))->execute();
     $this->assertEqual(array(), $alternate_c);
 }
コード例 #21
0
 public function executeConpherenceTransform(PhabricatorFile $file, $top, $left, $width, $height)
 {
     $image = $this->crasslyCropTo($file, $top, $left, $width, $height);
     return PhabricatorFile::newFromFileData($image, array('name' => 'conpherence-' . $file->getName(), 'canCDN' => true));
 }
コード例 #22
0
 private function buildRawFileResponse(DifferentialChangeset $changeset, $is_new)
 {
     $viewer = $this->getViewer();
     if ($is_new) {
         $key = 'raw:new:phid';
     } else {
         $key = 'raw:old:phid';
     }
     $metadata = $changeset->getMetadata();
     $file = null;
     $phid = idx($metadata, $key);
     if ($phid) {
         $file = id(new PhabricatorFileQuery())->setViewer($viewer)->withPHIDs(array($phid))->execute();
         if ($file) {
             $file = head($file);
         }
     }
     if (!$file) {
         // This is just building a cache of the changeset content in the file
         // tool, and is safe to run on a read pathway.
         $unguard = AphrontWriteGuard::beginScopedUnguardedWrites();
         if ($is_new) {
             $data = $changeset->makeNewFile();
         } else {
             $data = $changeset->makeOldFile();
         }
         $file = PhabricatorFile::newFromFileData($data, array('name' => $changeset->getFilename(), 'mime-type' => 'text/plain'));
         $metadata[$key] = $file->getPHID();
         $changeset->setMetadata($metadata);
         $changeset->save();
         unset($unguard);
     }
     return $file->getRedirectResponse();
 }
コード例 #23
0
ファイル: mail_handler.php プロジェクト: neoxen/phabricator
$text_body = $parser->getMessageBody('text');
$text_body_headers = $parser->getMessageBodyHeaders('text');
$content_type = idx($text_body_headers, 'content-type');
if (!phutil_is_utf8($text_body) && (preg_match('/charset="(.*?)"/', $content_type, $matches) || preg_match('/charset=(\\S+)/', $content_type, $matches))) {
    $text_body = phutil_utf8_convert($text_body, "UTF-8", $matches[1]);
}
$headers = $parser->getHeaders();
$headers['subject'] = iconv_mime_decode($headers['subject'], 0, "UTF-8");
$headers['from'] = iconv_mime_decode($headers['from'], 0, "UTF-8");
$received = new PhabricatorMetaMTAReceivedMail();
$received->setHeaders($headers);
$received->setBodies(array('text' => $text_body, 'html' => $parser->getMessageBody('html')));
$attachments = array();
foreach ($parser->getAttachments() as $attachment) {
    if (preg_match('@text/(plain|html)@', $attachment->getContentType()) && $attachment->getContentDisposition() == 'inline') {
        // If this is an "inline" attachment with some sort of text content-type,
        // do not treat it as a file for attachment. MimeMailParser already picked
        // it up in the getMessageBody() call above. We still want to treat 'inline'
        // attachments with other content types (e.g., images) as attachments.
        continue;
    }
    $file = PhabricatorFile::newFromFileData($attachment->getContent(), array('name' => $attachment->getFilename()));
    $attachments[] = $file->getPHID();
}
try {
    $received->setAttachments($attachments);
    $received->save();
    $received->processReceivedMail();
} catch (Exception $e) {
    $received->setMessage('EXCEPTION: ' . $e->getMessage())->save();
}
 private function refreshProfileImage(PhabricatorUserOAuthInfo $oauth_info)
 {
     $user = $this->getRequest()->getUser();
     $provider = $this->provider;
     $error = false;
     $userinfo_uri = new PhutilURI($provider->getUserInfoURI());
     $token = $oauth_info->getToken();
     try {
         $userinfo_uri->setQueryParam('access_token', $token);
         $user_data = HTTPSFuture::loadContent($userinfo_uri);
         $provider->setUserData($user_data);
         $provider->setAccessToken($token);
         $image = $provider->retrieveUserProfileImage();
         if ($image) {
             $file = PhabricatorFile::newFromFileData($image, array('name' => $provider->getProviderKey() . '-profile.jpg', 'authorPHID' => $user->getPHID()));
             $xformer = new PhabricatorImageTransformer();
             // Resize OAuth image to a reasonable size
             $small_xformed = $xformer->executeProfileTransform($file, $width = 50, $min_height = 50, $max_height = 50);
             $user->setProfileImagePHID($small_xformed->getPHID());
             $user->save();
         } else {
             $error = 'Unable to retrieve image.';
         }
     } catch (Exception $e) {
         if ($e instanceof PhabricatorOAuthProviderException) {
             $error = sprintf('Unable to retrieve image from %s', $provider->getProviderName());
         } else {
             $error = 'Unable to save image.';
         }
     }
     $notice = new AphrontErrorView();
     if ($error) {
         $notice->setTitle('Error Refreshing Profile Picture')->setErrors(array($error));
     } else {
         $notice->setSeverity(AphrontErrorView::SEVERITY_NOTICE)->setTitle('Successfully Refreshed Profile Picture');
     }
     return $notice;
 }
コード例 #25
0
ファイル: add_macro.php プロジェクト: nexeck/phabricator
 */
$root = dirname(dirname(dirname(__FILE__)));
require_once $root . '/scripts/__init_script__.php';
$args = new PhutilArgumentParser($argv);
$args->setTagline('load files as image macros');
$args->setSynopsis(<<<EOHELP
**add_macro.php** __image__ [--as __name__]
    Add an image macro. This can be useful for importing a large number
    of macros.
EOHELP
);
$args->parseStandardArguments();
$args->parse(array(array('name' => 'as', 'param' => 'name', 'help' => 'Use a specific name instead of the first part of the image ' . 'name.'), array('name' => 'more', 'wildcard' => true)));
$more = $args->getArg('more');
if (count($more) !== 1) {
    $args->printHelpAndExit();
}
$path = head($more);
$data = Filesystem::readFile($path);
$name = $args->getArg('as');
if ($name === null) {
    $name = head(explode('.', basename($path)));
}
$existing = id(new PhabricatorFileImageMacro())->loadOneWhere('name = %s', $name);
if ($existing) {
    throw new Exception("A macro already exists with the name '{$name}'!");
}
$file = PhabricatorFile::newFromFileData($data, array('name' => basename($path)));
$macro = id(new PhabricatorFileImageMacro())->setFilePHID($file->getPHID())->setName($name)->save();
$id = $file->getID();
echo "Added macro '{$name}' (F{$id}).\n";
コード例 #26
0
ファイル: mail_handler.php プロジェクト: pugong/phabricator
    $text_body = phutil_utf8_convert($text_body, 'UTF-8', $matches[1]);
}
$headers = $parser->getHeaders();
$headers['subject'] = iconv_mime_decode($headers['subject'], 0, 'UTF-8');
$headers['from'] = iconv_mime_decode($headers['from'], 0, 'UTF-8');
if ($args->getArg('process-duplicates')) {
    $headers['message-id'] = Filesystem::readRandomCharacters(64);
}
$received = new PhabricatorMetaMTAReceivedMail();
$received->setHeaders($headers);
$received->setBodies(array('text' => $text_body, 'html' => $parser->getMessageBody('html')));
$attachments = array();
foreach ($parser->getAttachments() as $attachment) {
    if (preg_match('@text/(plain|html)@', $attachment->getContentType()) && $attachment->getContentDisposition() == 'inline') {
        // If this is an "inline" attachment with some sort of text content-type,
        // do not treat it as a file for attachment. MimeMailParser already picked
        // it up in the getMessageBody() call above. We still want to treat 'inline'
        // attachments with other content types (e.g., images) as attachments.
        continue;
    }
    $file = PhabricatorFile::newFromFileData($attachment->getContent(), array('name' => $attachment->getFilename(), 'viewPolicy' => PhabricatorPolicies::POLICY_NOONE));
    $attachments[] = $file->getPHID();
}
try {
    $received->setAttachments($attachments);
    $received->save();
    $received->processReceivedMail();
} catch (Exception $e) {
    $received->setMessage(pht('EXCEPTION: %s', $e->getMessage()))->save();
    throw $e;
}
コード例 #27
0
 public function executePreviewTransform(PhabricatorFile $file, $size)
 {
     $image = $this->generatePreview($file, $size);
     return PhabricatorFile::newFromFileData($image, array('name' => 'preview-' . $file->getName()));
 }
コード例 #28
0
 public static function initializeFileForPaste(PhabricatorUser $actor, $name, $data)
 {
     return PhabricatorFile::newFromFileData($data, array('name' => $name, 'mime-type' => 'text/plain; charset=utf-8', 'authorPHID' => $actor->getPHID(), 'viewPolicy' => PhabricatorPolicies::POLICY_NOONE));
 }
コード例 #29
0
 private function writeChunk(PhabricatorFile $file, PhabricatorFileStorageEngine $engine)
 {
     $offset = $this->getTotalBytesWritten();
     $max_length = $engine->getChunkSize();
     $rope = $this->getRope();
     $data = $rope->getPrefixBytes($max_length);
     $actual_length = strlen($data);
     $rope->removeBytesFromHead($actual_length);
     $chunk_data = PhabricatorFile::newFromFileData($data, array('name' => $file->getMonogram() . '.chunk-' . $offset, 'viewPolicy' => PhabricatorPolicies::POLICY_NOONE));
     $chunk = PhabricatorFileChunk::initializeNewChunk($file->getStorageHandle(), $offset, $offset + $actual_length);
     $chunk->setDataFilePHID($chunk_data->getPHID())->save();
     $this->setTotalBytesWritten($offset + $actual_length);
     return $chunk;
 }
 public function processRequest()
 {
     $provider = $this->getOAuthProvider();
     $oauth_info = $this->getOAuthInfo();
     $request = $this->getRequest();
     $errors = array();
     $e_username = true;
     $e_email = true;
     $e_realname = true;
     $user = new PhabricatorUser();
     $user->setUsername($provider->retrieveUserAccountName());
     $user->setRealName($provider->retrieveUserRealName());
     $user->setEmail($provider->retrieveUserEmail());
     if ($request->isFormPost()) {
         $user->setUsername($request->getStr('username'));
         $username = $user->getUsername();
         if (!strlen($user->getUsername())) {
             $e_username = '******';
             $errors[] = 'Username is required.';
         } else {
             if (!PhabricatorUser::validateUsername($username)) {
                 $e_username = '******';
                 $errors[] = 'Username must consist of only numbers and letters.';
             } else {
                 $e_username = null;
             }
         }
         if ($user->getEmail() === null) {
             $user->setEmail($request->getStr('email'));
             if (!strlen($user->getEmail())) {
                 $e_email = 'Required';
                 $errors[] = 'Email is required.';
             } else {
                 $e_email = null;
             }
         }
         if (!strlen($user->getRealName())) {
             $user->setRealName($request->getStr('realname'));
             if (!strlen($user->getRealName())) {
                 $e_realname = 'Required';
                 $errors[] = 'Real name is required.';
             } else {
                 $e_realname = null;
             }
         }
         if (!$errors) {
             $image = $provider->retrieveUserProfileImage();
             if ($image) {
                 $file = PhabricatorFile::newFromFileData($image, array('name' => $provider->getProviderKey() . '-profile.jpg', 'authorPHID' => $user->getPHID()));
                 $user->setProfileImagePHID($file->getPHID());
             }
             try {
                 $user->save();
                 $oauth_info->setUserID($user->getID());
                 $oauth_info->save();
                 $session_key = $user->establishSession('web');
                 $request->setCookie('phusr', $user->getUsername());
                 $request->setCookie('phsid', $session_key);
                 return id(new AphrontRedirectResponse())->setURI('/');
             } catch (AphrontQueryDuplicateKeyException $exception) {
                 $same_username = id(new PhabricatorUser())->loadOneWhere('userName = %s', $user->getUserName());
                 $same_email = id(new PhabricatorUser())->loadOneWhere('email = %s', $user->getEmail());
                 if ($same_username) {
                     $e_username = '******';
                     $errors[] = 'That username or email is not unique.';
                 } else {
                     if ($same_email) {
                         $e_email = 'Duplicate';
                         $errors[] = 'That email is not unique.';
                     } else {
                         throw $exception;
                     }
                 }
             }
         }
     }
     $error_view = null;
     if ($errors) {
         $error_view = new AphrontErrorView();
         $error_view->setTitle('Registration Failed');
         $error_view->setErrors($errors);
     }
     // Strip the URI down to the path, because otherwise we'll trigger
     // external CSRF protection (by having a protocol in the form "action")
     // and generate a form with no CSRF token.
     $action_uri = new PhutilURI($provider->getRedirectURI());
     $action_path = $action_uri->getPath();
     $form = new AphrontFormView();
     $form->addHiddenInput('token', $provider->getAccessToken())->addHiddenInput('expires', $oauth_info->getTokenExpires())->addHiddenInput('state', $this->getOAuthState())->setUser($request->getUser())->setAction($action_path)->appendChild(id(new AphrontFormTextControl())->setLabel('Username')->setName('username')->setValue($user->getUsername())->setError($e_username));
     if ($provider->retrieveUserEmail() === null) {
         $form->appendChild(id(new AphrontFormTextControl())->setLabel('Email')->setName('email')->setValue($request->getStr('email'))->setError($e_email));
     }
     if ($provider->retrieveUserRealName() === null) {
         $form->appendChild(id(new AphrontFormTextControl())->setLabel('Real Name')->setName('realname')->setValue($request->getStr('realname'))->setError($e_realname));
     }
     $form->appendChild(id(new AphrontFormSubmitControl())->setValue('Create Account'));
     $panel = new AphrontPanelView();
     $panel->setHeader('Create New Account');
     $panel->setWidth(AphrontPanelView::WIDTH_FORM);
     $panel->appendChild($form);
     return $this->buildStandardPageResponse(array($error_view, $panel), array('title' => 'Create New Account'));
 }