Skip to content

Commit

Permalink
support for dumping all the exportable data from eZ; useful for expor…
Browse files Browse the repository at this point in the history
…ting from eZ Publish.
  • Loading branch information
dougplant committed Jan 31, 2017
1 parent 2779a3a commit d7b8daa
Show file tree
Hide file tree
Showing 5 changed files with 288 additions and 0 deletions.
7 changes: 7 additions & 0 deletions docs/modules_contentnode.md
Expand Up @@ -3,6 +3,7 @@
- [clearsubtreecache](#clearsubtreecache)
- [contentobject](#contentobject)
- [dump](#dump)
- [info](#info)
- [location](#location)
- [find](#find)
Expand All @@ -28,6 +29,12 @@ $ eep use contentnode <content node id>
$ eep contentnode contentobject
```

## dump
Dump all the data associated with a content node into an XML structure; suitable for dumping an eZ Publish instance for import into some other system, or etc.
```sh
$ eep contentnode dump <node id>
```

## info
Displays content node information.
```sh
Expand Down
3 changes: 3 additions & 0 deletions docs/modules_contentobject.md
Expand Up @@ -53,6 +53,9 @@ or
$ eep contentobject delete <object id>
```

## dump
Delete all content data, suitable for export from ez. See "eep contentnode dump".

## related
Displays a list of related content objects.
- supports use of ```--limit=N``` and ```--offset=M```
Expand Down
10 changes: 10 additions & 0 deletions docs/one_page.md
Expand Up @@ -362,6 +362,7 @@ $ eep contentclass setiscontainer <class identifier> <0|1>
- [clearsubtreecache](#clearsubtreecache)
- [contentobject](#contentobject)
- [dump](#dump)
- [info](#info)
- [location](#location)
- [find](#find)
Expand All @@ -387,6 +388,12 @@ $ eep use contentnode <content node id>
$ eep contentnode contentobject
```

## dump
Dump all the data associated with a content node into an XML structure; suitable for dumping an eZ Publish instance for import into some other system, or etc.
```sh
$ eep contentnode dump <node id>
```

## info
Displays content node information.
```sh
Expand Down Expand Up @@ -517,6 +524,9 @@ or
$ eep contentobject delete <object id>
```

## dump
Delete all content data, suitable for export from ez. See "eep contentnode dump".

## related
Displays a list of related content objects.
- supports use of ```--limit=N``` and ```--offset=M```
Expand Down
44 changes: 44 additions & 0 deletions lib/eepHelpers.php
Expand Up @@ -703,5 +703,49 @@ public static function fixBadQuestionMarks( $xml )
}
return $xml;
}

//------------------------------------------------------------------------------
// kind of a multipurpose thing; mainly write an XML tag along with the desired data:
// <tag>blah blah blah</tag>
// by setting $data to null, can also write just an open or close tag:
// <tag>
// the benefit is that that it makes the output homogeneous to call and supports indenting
function writeXMLTag( $indent, $tag, $data )
{
$padding = str_pad( "", $indent );
$data = eep::escapeForXML( $data );
if( strstr( $data, "?xml version=\"1.0\"" ) )
{
$data = preg_replace( "/\s\s+/", " ", $data );
}

echo $padding . "<" . $tag . ">" . trim( $data );

if( null === $data )
{
echo "\n";
}
else
{
echo "</" . $tag . ">\n";
}
}

//------------------------------------------------------------------------------
// Make a string safe for embedding in XML, mostly used for escaping XML so
// that it can be carried in some other XML structure. Can be run on any string,
// doesn't have to originally be XML.
function escapeForXML( $str )
{
// don't accidentally convert a null to a string -- because we care
if( null === $str) return null;

// remove all entities
$str = html_entity_decode( $str );
// do ampersands first, so as to not escape the lt's
$str = str_replace( "&", "&amp;", $str );
$str = str_replace( "<", "&lt;", $str );
return $str;
}
}
?>
224 changes: 224 additions & 0 deletions modules/contentnode/index.php
Expand Up @@ -13,6 +13,7 @@ class contentnode_commands
{
const contentnode_clearsubtreecache = "clearsubtreecache";
const contentnode_contentobject = "contentobject";
const contentnode_dump = "dump";
const contentnode_info = "info";
const contentnode_location = "location";
const contentnode_find = "find";
Expand All @@ -29,6 +30,7 @@ class contentnode_commands
, self::contentnode_clearsubtreecache
, self::contentnode_contentobject
, self::contentnode_deletesubtree
, self::contentnode_dump
, self::contentnode_find
, self::contentnode_info
, self::contentnode_location
Expand Down Expand Up @@ -66,6 +68,10 @@ public function __construct()
... or
eep use contentnode <subtree node id>
eep contentnode deletesubtree
dump
- dump all the data associated with a content node into an XML structure; suitable for dumping an eZ Publish instance for import into some other system, or etc.
eep contentnode dump <node id>
find
- supports --limit=N and/or --offset=M
Expand Down Expand Up @@ -485,6 +491,219 @@ private function unhidesubtree( $nodeId )
eZContentObjectTreeNode::unhideSubTree( $node );
}

//--------------------------------------------------------------------------
const dump_interestingNodeMembers = array
(
"Name"
, "MainNodeID"
, "NodeID"
, "ClassIdentifier"
, "ParentNodeID"
, "ContentObjectID"
, "ContentObjectVersion"
, "ContentObjectIsPublished"
, "Depth"
, "SortField"
, "SortOrder"
, "Priority"
, "ModifiedSubNode"
, "PathString"
, "PathIdentificationString"
, "RemoteID"
, "IsHidden"
, "IsInvisible"
);

const dump_interestingContentObjectMembers = array
(
"ID"
, "SectionID"
, "OwnerID"
, "Published"
, "Modified"
, "CurrentVersion"
, "Status"
);

const dump_userAttributes = array
(
"Login"
, "Email"
, "PasswordHash"
, "PasswordHashType"
//, "PersistentDataDirty"
, "Groups"
, "OriginalPassword"
, "OriginalPasswordConfirm"
, "ContentObjectID"
);

const dump_interestingAttributeMembers = array
(
"ID"
//, "PersistentDataDirty"
, "HTTPValue"
, "Content"
, "DisplayInfo"
, "IsValid"
, "ContentClassAttributeID"
//, "ValidationError"
//, "ValidationLog"
, "ContentClassAttributeIdentifier"
, "ContentClassAttributeCanTranslate"
, "ContentClassAttributeName"
, "ContentClassAttributeIsInformationCollector"
, "ContentClassAttributeIsRequired"
//, "InputParameters"
//, "HasValidationError"
, "DataTypeCustom"
, "ContentObjectID"
, "Version"
, "LanguageCode"
, "AttributeOriginalID"
, "SortKeyInt"
, "SortKeyString"
, "DataTypeString"
, "DataText"
, "DataInt"
, "DataFloat"
);


//--------------------------------------------------------------------------
// kind of a massive function using a bunch of furniture; look at the furniture
// for how to tweak the export to suit your purposes
private function dumpNodeToXML( $nodeId )
{
// need to operate in a privileged account
$adminUserObject = eZUser::fetch( eepSetting::PrivilegedAccountId );
$adminUserObject->loginCurrent();

$needToDumpeZUserData = false;

if( !eepValidate::validateContentNodeId( $nodeId ) )
throw new Exception( "This is not a node id: [" .$nodeId. "]" );

$eepLogger = new eepLog( eepSetting::LogFolder, eepSetting::LogFile );

$node = eZFunctionHandler::execute( "content", "node", array( "node_id" => $nodeId ) );
//print_r( $node );

$contentClassIdentifier = $node->ClassIdentifier;

eep::writeXMLTag( 0, "item", null );
eep::writeXMLTag( 4, "node", null );
// dump the interesting data for the node
foreach( contentnode_commands::dump_interestingNodeMembers as $member )
{
if( isset( $node->$member ) )
{
eep::writeXMLTag( 8, $member, $node->$member );
}
else
{
$eepLogger->Report( "Node-member not available: ".$member, "error" );
}
}
eep::writeXMLTag( 4, "/node", null );

// dump the interesting data for the content object
$object = $node->attribute( 'object' );
eep::writeXMLTag( 4, "content-object", null );
foreach( contentnode_commands::dump_interestingContentObjectMembers as $member )
{
if( isset( $object->$member ) )
{
eep::writeXMLTag( 8, $member, $object->$member );
}
else
{
$eepLogger->Report( "Content-object-member not available: ".$member, "error" );
}
}
eep::writeXMLTag( 4, "/content-object", null );

// get list of active languages
$activeLanguageStructs = eZContentLanguage::fetchList( true );
$activeLanguages = array();
foreach( $activeLanguageStructs as $als )
{
$activeLanguages[] = $als->Locale;
}
//print_r( $activeLanguages );

// dump all the attributes, associated by translation
eep::writeXMLTag( 4, "attributes", null );
foreach( $activeLanguages as $languageCode )
{
// get the datamap associated with a specific language
$datamap = eZFunctionHandler::execute
(
"content"
, "contentobject_attributes"
, array
(
"version" => $object->attribute( "current" )
, "language_code" => $languageCode
)
);
//print_r( $datamap );
eep::writeXMLTag( 8, "language language-code='" . $languageCode . "'", null );
foreach( $datamap as $attributeIdentifier => $attribute )
{
if( "ezuuser" == $attribute->DataTypeString ) // special case, handled below
{
$contentClassIdentifier = true;
}
else
{
$contentClassIdentifier = false;
}
//echo "\n\n" . $attribute->DataTypeString . "\n\n";

eep::writeXMLTag( 12, "attribute", null );
foreach( contentnode_commands::dump_interestingAttributeMembers as $member )
{
if( "DataText"==$member && "ezxmltext"==$attribute->DataTypeString )
{
$ezText = new eZXMLText( $attribute->DataText, $attribute );
$oh = $ezText->attribute( "output" );
eep::writeXMLTag( 16, "DataText", "" . $oh->attribute( "output_text" ) );
}
elseif( "Content"==$member && "ezbinaryfile"==$attribute->DataTypeString )
{
eep::writeXMLTag( 16, "Content", serialize( $attribute->content() ) ); // for, eg, ezbinaryfile->Content ... is an object
}
else
{
eep::writeXMLTag( 16, $member, "" . $attribute->$member );
}
}
eep::writeXMLTag( 12, "/attribute", null );
}
eep::writeXMLTag( 8, "/language", null );
}
eep::writeXMLTag( 4, "/attributes", null );

// special case, content class uses the magical ezuser datatype to designate a system user
if( $needToDumpeZUserData )
{
if( "user" == $contentClassIdentifier )
{
eep::writeXMLTag( 4, "user", null );
$user = eZUser::fetch( $object->ID );
foreach( contentnode_commands::dump_userAttributes as $member )
{
eep::writeXMLTag( 8, $member, $user->$member );
}
eep::writeXMLTag( 4, "/user", null );
}
}
eep::writeXMLTag( 0, "/item", null );

$adminUserObject->logoutCurrent();
}

//--------------------------------------------------------------------------
public function run( $argv, $additional )
{
Expand Down Expand Up @@ -538,6 +757,11 @@ public function run( $argv, $additional )
$this->deleteSubtree( $subtreeNodeId, $additional );
break;

case self::contentnode_dump:
$nodeId = $param1;
echo $this->dumpNodeToXML( $nodeId );
break;

case self::contentnode_contentobject:
$nodeId = $eepCache->readFromCache( eepCache::use_key_contentnode );
if( $param1 )
Expand Down

0 comments on commit d7b8daa

Please sign in to comment.