[ Index ]

PHP Cross Reference of Phabricator

title

Body

[close]

/src/view/form/ -> PHUIPagedFormView.php (source)

   1  <?php
   2  
   3  /**
   4   * @task page   Managing Pages
   5   */
   6  final class PHUIPagedFormView extends AphrontTagView {
   7  
   8    private $name = 'pages';
   9    private $pages = array();
  10    private $selectedPage;
  11    private $choosePage;
  12    private $nextPage;
  13    private $prevPage;
  14    private $complete;
  15    private $cancelURI;
  16  
  17    protected function canAppendChild() {
  18      return false;
  19    }
  20  
  21  
  22  /* -(  Managing Pages  )----------------------------------------------------- */
  23  
  24  
  25    /**
  26     * @task page
  27     */
  28    public function addPage($key, PHUIFormPageView $page) {
  29      if (isset($this->pages[$key])) {
  30        throw new Exception("Duplicate page with key '{$key}'!");
  31      }
  32      $this->pages[$key] = $page;
  33      $page->setPagedFormView($this, $key);
  34  
  35      $this->selectedPage = null;
  36      $this->complete = null;
  37  
  38      return $this;
  39    }
  40  
  41  
  42    /**
  43     * @task page
  44     */
  45    public function getPage($key) {
  46      if (!$this->pageExists($key)) {
  47        throw new Exception("No page '{$key}' exists!");
  48      }
  49      return $this->pages[$key];
  50    }
  51  
  52  
  53    /**
  54     * @task page
  55     */
  56    public function pageExists($key) {
  57      return isset($this->pages[$key]);
  58    }
  59  
  60  
  61    /**
  62     * @task page
  63     */
  64    protected function getPageIndex($key) {
  65      $page = $this->getPage($key);
  66  
  67      $index = 0;
  68      foreach ($this->pages as $target_page) {
  69        if ($page === $target_page) {
  70          break;
  71        }
  72        $index++;
  73      }
  74  
  75      return $index;
  76    }
  77  
  78  
  79    /**
  80     * @task page
  81     */
  82    protected function getPageByIndex($index) {
  83      foreach ($this->pages as $page) {
  84        if (!$index) {
  85          return $page;
  86        }
  87        $index--;
  88      }
  89  
  90      throw new Exception("Requesting out-of-bounds page '{$index}'.");
  91    }
  92  
  93    protected function getLastIndex() {
  94      return count($this->pages) - 1;
  95    }
  96  
  97    protected function isFirstPage(PHUIFormPageView $page) {
  98      return ($this->getPageIndex($page->getKey()) === 0);
  99  
 100    }
 101  
 102    protected function isLastPage(PHUIFormPageView $page) {
 103      return ($this->getPageIndex($page->getKey()) === (count($this->pages) - 1));
 104    }
 105  
 106    public function getSelectedPage() {
 107      return $this->selectedPage;
 108    }
 109  
 110    public function readFromObject($object) {
 111      return $this->processForm($is_request = false, $object);
 112    }
 113  
 114    public function writeToResponse($response) {
 115      foreach ($this->pages as $page) {
 116        $page->validateResponseType($response);
 117        $response = $page->writeToResponse($page);
 118      }
 119  
 120      return $response;
 121    }
 122  
 123    public function readFromRequest(AphrontRequest $request) {
 124      $this->choosePage = $request->getStr($this->getRequestKey('page'));
 125      $this->nextPage = $request->getStr('__submit__');
 126      $this->prevPage = $request->getStr('__back__');
 127  
 128      return $this->processForm($is_request = true, $request);
 129    }
 130  
 131    public function setName($name) {
 132      $this->name = $name;
 133      return $this;
 134    }
 135  
 136  
 137    public function getValue($page, $key, $default = null) {
 138      return $this->getPage($page)->getValue($key, $default);
 139    }
 140  
 141    public function setValue($page, $key, $value) {
 142      $this->getPage($page)->setValue($key, $value);
 143      return $this;
 144    }
 145  
 146    private function processForm($is_request, $source) {
 147      if ($this->pageExists($this->choosePage)) {
 148        $selected = $this->getPage($this->choosePage);
 149      } else {
 150        $selected = $this->getPageByIndex(0);
 151      }
 152  
 153      $is_attempt_complete = false;
 154      if ($this->prevPage) {
 155        $prev_index = $this->getPageIndex($selected->getKey()) - 1;;
 156        $index = max(0, $prev_index);
 157        $selected = $this->getPageByIndex($index);
 158      } else if ($this->nextPage) {
 159        $next_index = $this->getPageIndex($selected->getKey()) + 1;
 160        if ($next_index > $this->getLastIndex()) {
 161          $is_attempt_complete = true;
 162        }
 163        $index = min($this->getLastIndex(), $next_index);
 164        $selected = $this->getPageByIndex($index);
 165      }
 166  
 167      $validation_error = false;
 168      $found_selected = false;
 169      foreach ($this->pages as $key => $page) {
 170        if ($is_request) {
 171          if ($key === $this->choosePage) {
 172            $page->readFromRequest($source);
 173          } else {
 174            $page->readSerializedValues($source);
 175          }
 176        } else {
 177          $page->readFromObject($source);
 178        }
 179  
 180        if (!$found_selected) {
 181          $page->adjustFormPage();
 182        }
 183  
 184        if ($page === $selected) {
 185          $found_selected = true;
 186        }
 187  
 188        if (!$found_selected || $is_attempt_complete) {
 189          if (!$page->isValid()) {
 190            $selected = $page;
 191            $validation_error = true;
 192            break;
 193          }
 194        }
 195      }
 196  
 197      if ($is_attempt_complete && !$validation_error) {
 198        $this->complete = true;
 199      } else {
 200        $this->selectedPage = $selected;
 201      }
 202  
 203      return $this;
 204    }
 205  
 206    public function isComplete() {
 207      return $this->complete;
 208    }
 209  
 210    public function getRequestKey($key) {
 211      return $this->name.':'.$key;
 212    }
 213  
 214    public function setCancelURI($cancel_uri) {
 215      $this->cancelURI = $cancel_uri;
 216      return $this;
 217    }
 218  
 219    public function getCancelURI() {
 220      return $this->cancelURI;
 221    }
 222  
 223    public function getTagContent() {
 224      $form = id(new AphrontFormView())
 225        ->setUser($this->getUser());
 226  
 227      $selected_page = $this->getSelectedPage();
 228      if (!$selected_page) {
 229        throw new Exception('No selected page!');
 230      }
 231  
 232      $form->addHiddenInput(
 233        $this->getRequestKey('page'),
 234        $selected_page->getKey());
 235  
 236      $errors = array();
 237  
 238      foreach ($this->pages as $page) {
 239        if ($page == $selected_page) {
 240          $errors = $page->getPageErrors();
 241          continue;
 242        }
 243        foreach ($page->getSerializedValues() as $key => $value) {
 244          $form->addHiddenInput($key, $value);
 245        }
 246      }
 247  
 248      $submit = id(new PHUIFormMultiSubmitControl());
 249  
 250      if (!$this->isFirstPage($selected_page)) {
 251        $submit->addBackButton();
 252      } else if ($this->getCancelURI()) {
 253        $submit->addCancelButton($this->getCancelURI());
 254      }
 255  
 256      if ($this->isLastPage($selected_page)) {
 257        $submit->addSubmitButton(pht('Save'));
 258      } else {
 259        $submit->addSubmitButton(pht("Continue \xC2\xBB"));
 260      }
 261  
 262      $form->appendChild($selected_page);
 263      $form->appendChild($submit);
 264  
 265      $box = id(new PHUIObjectBoxView())
 266        ->setFormErrors($errors)
 267        ->setForm($form);
 268  
 269      if ($selected_page->getPageName()) {
 270        $header = id(new PHUIHeaderView())
 271          ->setHeader($selected_page->getPageName());
 272        $box->setHeader($header);
 273      }
 274  
 275      return $box;
 276    }
 277  
 278  }


Generated: Sun Nov 30 09:20:46 2014 Cross-referenced by PHPXref 0.7.1