/**
  * Prepare the page and it's fields for removal from runtime memory, called primarily by Pages::uncache()
  *
  */
 public function uncache()
 {
     $trackChanges = $this->trackChanges();
     if ($trackChanges) {
         $this->setTrackChanges(false);
     }
     if ($this->template) {
         foreach ($this->template->fieldgroup as $field) {
             $value = parent::get($field->name);
             if ($value != null && is_object($value)) {
                 if (method_exists($value, 'uncache') && $value !== $this) {
                     $value->uncache();
                 }
                 parent::set($field->name, null);
             }
         }
     }
     if ($this->filesManager) {
         $this->filesManager->uncache();
     }
     $this->filesManager = null;
     if ($trackChanges) {
         $this->setTrackChanges(true);
     }
 }
Beispiel #2
0
 /**
  * Clone an entire page, it's assets and children and return it. 
  *
  * @param Page $page Page that you want to clone
  * @param Page $parent New parent, if different (default=same parent)
  * @param bool $recursive Clone the children too? (default=true)
  * @param array|string $options Optional options that can be passed to clone or save
  * 	- forceID (int): force a specific ID
  * 	- set (array): Array of properties to set to the clone (you can also do this later)
  * 	- recursionLevel (int): recursion level, for internal use only. 
  * @return Page the newly cloned page or a NullPage() with id=0 if unsuccessful.
  * @throws WireException|Exception on fatal error
  *
  */
 public function ___clone(Page $page, Page $parent = null, $recursive = true, $options = array())
 {
     if (is_string($options)) {
         $options = Selectors::keyValueStringToArray($options);
     }
     if (!isset($options['recursionLevel'])) {
         $options['recursionLevel'] = 0;
     }
     // recursion level
     // if parent is not changing, we have to modify name now
     if (is_null($parent)) {
         $parent = $page->parent;
         $n = 1;
         $name = $page->name . '-' . $n;
     } else {
         $name = $page->name;
         $n = 0;
     }
     // make sure that we have a unique name
     while (count($parent->children("name={$name}, include=all"))) {
         $name = $page->name;
         $nStr = "-" . ++$n;
         if (strlen($name) + strlen($nStr) > self::nameMaxLength) {
             $name = substr($name, 0, self::nameMaxLength - strlen($nStr));
         }
         $name .= $nStr;
     }
     // Ensure all data is loaded for the page
     foreach ($page->template->fieldgroup as $field) {
         $page->get($field->name);
     }
     // clone in memory
     $copy = clone $page;
     $copy->id = isset($options['forceID']) ? (int) $options['forceID'] : 0;
     $copy->setIsNew(true);
     $copy->name = $name;
     $copy->parent = $parent;
     // set any properties indicated in options
     if (isset($options['set']) && is_array($options['set'])) {
         foreach ($options['set'] as $key => $value) {
             $copy->set($key, $value);
         }
         if (isset($options['set']['modified'])) {
             $options['quiet'] = true;
             // allow for modified date to be set
             if (!isset($options['set']['modified_users_id'])) {
                 // since 'quiet' also allows modified user to be set, make sure that it
                 // is still updated, if not specifically set.
                 $copy->modified_users_id = $this->wire('user')->id;
             }
         }
         if (isset($options['set']['modified_users_id'])) {
             $options['quiet'] = true;
             // allow for modified user to be set
             if (!isset($options['set']['modified'])) {
                 // since 'quiet' also allows modified tie to be set, make sure that it
                 // is still updated, if not specifically set.
                 $copy->modified = time();
             }
         }
     }
     // tell PW that all the data needs to be saved
     foreach ($copy->template->fieldgroup as $field) {
         $copy->trackChange($field->name);
     }
     $o = $copy->outputFormatting;
     $copy->setOutputFormatting(false);
     $this->cloneReady($page, $copy);
     try {
         $this->cloning = true;
         $options['ignoreFamily'] = true;
         // skip family checks during clone
         $this->save($copy, $options);
     } catch (Exception $e) {
         $this->cloning = false;
         throw $e;
     }
     $this->cloning = false;
     $copy->setOutputFormatting($o);
     // check to make sure the clone has worked so far
     if (!$copy->id || $copy->id == $page->id) {
         return new NullPage();
     }
     // copy $page's files over to new page
     if (PagefilesManager::hasFiles($page)) {
         $copy->filesManager->init($copy);
         $page->filesManager->copyFiles($copy->filesManager->path());
     }
     // if there are children, then recurisvely clone them too
     if ($page->numChildren && $recursive) {
         $start = 0;
         $limit = 200;
         do {
             $children = $page->children("include=all, start={$start}, limit={$limit}");
             $numChildren = $children->count();
             foreach ($children as $child) {
                 /** @var Page $child */
                 $this->clone($child, $copy, true, array('recursionLevel' => $options['recursionLevel'] + 1));
             }
             $start += $limit;
             $this->uncacheAll();
         } while ($numChildren);
     }
     $copy->parentPrevious = null;
     // update pages_parents table, only when at recursionLevel 0 since pagesParents is already recursive
     if ($recursive && $options['recursionLevel'] === 0) {
         $this->saveParents($copy->id, $copy->numChildren);
     }
     $copy->resetTrackChanges();
     $this->cloned($page, $copy);
     $this->debugLog('clone', "page={$page}, parent={$parent}", $copy);
     return $copy;
 }
Beispiel #3
0
 /**
  * Clone an entire page, it's assets and children and return it. 
  *
  * @param Page $page Page that you want to clone
  * @param Page $parent New parent, if different (default=same parent)
  * @param bool $recursive Clone the children too? (default=true)
  * @param array $options Optional options that can be passed to clone or save
  * 	- forceID (int): force a specific ID
  * 	- set (array): Array of properties to set to the clone (you can also do this later)
  * @return Page the newly cloned page or a NullPage() with id=0 if unsuccessful.
  *
  */
 public function ___clone(Page $page, Page $parent = null, $recursive = true, $options = array())
 {
     // if parent is not changing, we have to modify name now
     if (is_null($parent)) {
         $parent = $page->parent;
         $n = 1;
         $name = $page->name . '-' . $n;
     } else {
         $name = $page->name;
         $n = 0;
     }
     // make sure that we have a unique name
     while (count($parent->children("name={$name}, include=all"))) {
         $name = $page->name . '-' . ++$n;
     }
     // Ensure all data is loaded for the page
     foreach ($page->template->fieldgroup as $field) {
         $page->get($field->name);
     }
     // clone in memory
     $copy = clone $page;
     $copy->id = isset($options['forceID']) ? (int) $options['forceID'] : 0;
     $copy->setIsNew(true);
     $copy->name = $name;
     $copy->parent = $parent;
     // set any properties indicated in options
     if (isset($options['set']) && is_array($options['set'])) {
         foreach ($options['set'] as $key => $value) {
             $copy->set($key, $value);
         }
     }
     // tell PW that all the data needs to be saved
     foreach ($copy->template->fieldgroup as $field) {
         $copy->trackChange($field->name);
     }
     $o = $copy->outputFormatting;
     $copy->setOutputFormatting(false);
     $this->cloneReady($page, $copy);
     $this->save($copy, $options);
     $copy->setOutputFormatting($o);
     // check to make sure the clone has worked so far
     if (!$copy->id || $copy->id == $page->id) {
         return new NullPage();
     }
     // copy $page's files over to new page
     if (PagefilesManager::hasFiles($page)) {
         $copy->filesManager->init($copy);
         $page->filesManager->copyFiles($copy->filesManager->path());
     }
     // if there are children, then recurisvely clone them too
     if ($page->numChildren && $recursive) {
         foreach ($page->children("include=all") as $child) {
             $this->clone($child, $copy);
         }
     }
     $copy->parentPrevious = null;
     $copy->resetTrackChanges();
     $this->cloned($page, $copy);
     $this->debugLog('clone', "page={$page}, parent={$parent}", $copy);
     return $copy;
 }