Skip to content

Instantly share code, notes, and snippets.

@sepiariver
Last active January 8, 2019 20:58
Show Gist options
  • Save sepiariver/390db41a9ddcaeb5a27f to your computer and use it in GitHub Desktop.
Save sepiariver/390db41a9ddcaeb5a27f to your computer and use it in GitHub Desktop.
A Snippet to clone a Resource into multiple, user-defined parent containers in arbitrary contexts
<?php
// get user-defined source document and target parents
$source = intval($modx->getOption('sourceId', $scriptProperties, ''));
$targets = array_map('trim', explode(',', $modx->getOption('targetIds', $scriptProperties, '')));
// to prevent accidents...
$_allowedUsers = explode(',', 'username1,username2');
// check stuff, and if passed then get the source document object
if ( !in_array($modx->user->get('username'), $_allowedUsers) || empty($source) || $source == 0 || !is_array($targets) || empty($targets) ) return;
$sourceDoc = $modx->getObject('modResource', $source);
// loop through the defined target parents, create new child objects with overrides
foreach ($targets as $target) {
$parent = intval($target);
$parentDoc = $modx->getObject('modResource', $parent);
if ( !is_object($parentDoc) ) continue;
// the duplicate() method is pretty rad, Jason!
$newDoc = $sourceDoc->duplicate(array(
'newName' => $modx->getOption('name', $scriptProperties, ''),
'parent' => $parent,
'duplicateChildren' => $modx->getOption('duplicate_children', $scriptProperties, true),
'prefixDuplicate' => $modx->getOption('prefixDuplicate', $scriptProperties, false),
'publishedMode' => $modx->getOption('published_mode', $scriptProperties, 'unpublish'),
'overrides' => array('context_key' => $parentDoc->get('context_key')),
));
$output[] = $newDoc->get('id');
}
// what happened? this is very basic reporting. Could do with some calls to MODX log
return implode(', ', $output);
@sepiariver
Copy link
Author

Use Cases

Any time you want to deploy copies of a Resource to multiple "locations" in the MODX Tree. For example you may want to quickly clone a child Resource because it represents a part of the content model displayed by its parent Resource. Or another more specific example might be something like:

You have a site with multiple Contexts, each representing a Location. Each Context has roughly (but not exactly) the same structure of Resources, and those Resources have similar but not identical content. When you publish a new Resource in one Context, often you need to duplicate it to the other Contexts. Sometimes those Resources have child Resources that you also want to duplicate. Sometimes the Resource you want to copy is itself a child of another, and you want to set multiple targets to which the new duplicated Resources will be copied. The "Duplicate" right-click menu item doesn't do it, but this Snippet does.

Example Usage

[[!cloneResource? &sourceId=`969` &targetIds=`1229,3029` &published_mode=`preserve`]]

Installation

Create a new Snippet with above code, and add allowed usernames to the comma-separated list on line 6.

Uses the duplicate() method here: https://github.com/modxcms/revolution/blob/release-2.2/core/model/modx/modresource.class.php

Important

The Snippet will run every time you request the calling Resource, if you're an allowed user. This would result in multiple duplications, if you leave it lying around. Suggested use is to call it from an unpublished Resource, hidden from menus, and when you're done duplicating, remove the Snippet call!

Tips and Tricks

Thanks again to @opengeek for pointing out most of the following (and for writing the method)

  1. In the array of options passed to the duplicate method, note that you can override the parent with the 'parent' array element — otherwise the duplicate resources will have the same parent as the source.
  2. Other fields can be overridden using the 'overrides' element, which takes an array of override key/value pairs. Setting arbitrary 'parent' values without a corresponding 'context_key' value will probably yield unpredictable results.

@tjventurini
Copy link

very usefull 👍

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment