| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -1,201 +1 @@ | ||
| # Configuration |
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,10 @@ | ||
| { | ||
| "$schema": "slice-attachment.json", | ||
| "version": "1.0.0", | ||
| "type": "php", | ||
| "tag": "attachment", | ||
| "meta": { | ||
| "entity": "attachment" | ||
| }, | ||
| "data": "https://www.example.com/attachment.jpg" | ||
| } |
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,46 @@ | ||
| { | ||
| "$schema": "http://json-schema.org/draft-07/schema", | ||
| "title": "Impex Content Slice", | ||
| "description": "a Impex slice containing content", | ||
| "type": "object", | ||
| "properties": { | ||
| "$schema": { | ||
| "type": "string", | ||
| "description": "The JSON schema for this slice" | ||
| }, | ||
| "version": { | ||
| "title": "Impex Provider content version", | ||
| "description": "Version will be used by Impex to know what data format to expect", | ||
| "const": "1.0.0" | ||
| }, | ||
| "type": { | ||
| "title": "Impex slice type", | ||
| "description": "Value will be used by Impex to know the content type of the slice", | ||
| "const": "php" | ||
| }, | ||
| "tag": { | ||
| "title": "Impex slice tag", | ||
| "description": "The Impex slice tag contains information about the responsible Impex provider for this slice", | ||
| "const": "attachment" | ||
| }, | ||
| "meta": { | ||
| "title": "Metadata for the slice", | ||
| "description": "Metadata is a JSON object used to store additional information about the slice", | ||
| "const": { | ||
| "entity": "attachment" | ||
| } | ||
| }, | ||
| "data": { | ||
| "format": "uri-template", | ||
| "type": "string", | ||
| "title": "Data portion of this Impex slice", | ||
| "description": "Attachment slice data is expected to be a URI to the attachment file.\nFor media it has to be the URI to the image.\nURI can be absolute or relative.", | ||
| "examples": [ | ||
| "./media/image.jpg", | ||
| "https://www.example.com/attachment.jpg" | ||
| ] | ||
| } | ||
| }, | ||
| "additionalProperties": false, | ||
| "required": ["version", "type", "tag", "meta", "data"] | ||
| } |
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,23 @@ | ||
| { | ||
| "$schema": "slice-content.json", | ||
| "version": "1.0.0", | ||
| "type": "php", | ||
| "tag": "content-exporter", | ||
| "meta": { | ||
| "entity": "content-exporter" | ||
| }, | ||
| "data": { | ||
| "posts": [ | ||
| { | ||
| "wp:post_id": 1, | ||
| "title": "Home", | ||
| "wp:post_content": "<!-- wp:paragraph -->\n<p>Hello from first imported post !</p>\n<!-- /wp:paragraph -->" | ||
| }, | ||
| { | ||
| "wp:post_id": 2, | ||
| "title": "About", | ||
| "wp:post_content": "<!-- wp:paragraph -->\n<p>Hello from \"second imported post\" !</p>\n<!-- /wp:paragraph -->" | ||
| } | ||
| ] | ||
| } | ||
| } |
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,119 @@ | ||
| { | ||
| "$schema": "http://json-schema.org/draft-07/schema", | ||
| "title": "Impex Content Slice", | ||
| "description": "a Impex slice containing content", | ||
| "type": "object", | ||
| "properties": { | ||
| "$schema": { | ||
| "type": "string", | ||
| "description": "The JSON schema for this slice" | ||
| }, | ||
| "version": { | ||
| "title": "Impex Provider content version", | ||
| "description": "Version will be used by Impex to know what data format to expect", | ||
| "const": "1.0.0" | ||
| }, | ||
| "type": { | ||
| "title": "Impex slice type", | ||
| "description": "Value will be used by Impex to know the content type of the slice", | ||
| "const": "php" | ||
| }, | ||
| "tag": { | ||
| "title": "Impex slice tag", | ||
| "description": "The Impex slice tag contains information about the responsible Impex provider for this slice", | ||
| "const": "content-exporter" | ||
| }, | ||
| "meta": { | ||
| "title": "Metadata for the slice", | ||
| "description": "Metadata is a JSON object used to store additional information about the slice", | ||
| "const": { | ||
| "entity": "content-exporter" | ||
| } | ||
| }, | ||
| "data": { | ||
| "type": "object", | ||
| "properties": { | ||
| "posts": { | ||
| "type": "array", | ||
| "items": { | ||
| "$ref": "#/definitions/posts-item" | ||
| }, | ||
| "minItems": 1, | ||
| "$comment": "@TODO: unique ids are not yet supported by jsonschema", | ||
| "uniqueItems": true | ||
| } | ||
| }, | ||
| "title": "Data portion of this Impex slice", | ||
| "description": "data contains the real Impex data.", | ||
| "required": ["posts"] | ||
| } | ||
| }, | ||
| "additionalProperties": false, | ||
| "required": ["version", "type", "tag", "meta", "data"], | ||
| "definitions": { | ||
| "posts-item": { | ||
| "title": "WordPress posts stored in this this Impex slice", | ||
| "type": "object", | ||
| "properties": { | ||
| "wp:post_id": { | ||
| "type": "integer", | ||
| "minimum": 1, | ||
| "title": "WordPress post_id", | ||
| "description": "The unique WordPress post id of the post" | ||
| }, | ||
| "title": { | ||
| "type": "string", | ||
| "minLength": 1, | ||
| "title": "WordPress post title", | ||
| "description": "The title of the WordPress post as it is stored in the database" | ||
| }, | ||
| "wp:post_content": { | ||
| "type": "string", | ||
| "minLength": 1, | ||
| "title": "WordPress post content", | ||
| "description": "The content of the WordPress post", | ||
| "examples": [ | ||
| "<!-- wp:paragraph -->\n<p>Hello from first imported post !</p>\n<!-- /wp:paragraph -->", | ||
| "<!-- wp:paragraph -->\n<p>Hello world</p>\n<!-- /wp:paragraph -->\n\n<!-- wp:html -->\n<p>A bit of custom html utilizing the Gutenberg html block</p>\n<ul>\n <li>hi</li>\n <li>ho</li>\n <li>howdy</li>\n</ul><!-- /wp:html -->" | ||
| ] | ||
| }, | ||
| "wp:post_type": { | ||
| "title": "WordPress post type", | ||
| "description": "The type of the WordPress post.\nCcontent related post types are 'post' and 'page'.\nIf not declared, type 'post' will be assumed.", | ||
| "type": "string", | ||
| "enum": [ | ||
| "post", | ||
| "page", | ||
| "nav_menu_item", | ||
| "wp_template", | ||
| "wp_template_part", | ||
| "wp_block", | ||
| "wp_global_styles" | ||
| ], | ||
| "default": "page" | ||
| }, | ||
| "wp:status": { | ||
| "type": "string", | ||
| "title": "WordPress post status", | ||
| "description": "The WordPress post status (https://wordpress.org/support/article/post-status/)", | ||
| "enum": ["publish", "future", "draft", "pending", "private"], | ||
| "default": "draft" | ||
| }, | ||
| "wp:post_name": { | ||
| "type": "string", | ||
| "title": "WordPress post slug", | ||
| "description": "Used to generate the permalink. If not given, the sanitized post title will be used instead.", | ||
| "minLength": 1 | ||
| }, | ||
| "wp:post_parent": { | ||
| "type": "integer", | ||
| "minimum": 1, | ||
| "title": "WordPress post parent id", | ||
| "description": "The WordPress post id of the parent post.\n If not given, the post will be created as a top level post." | ||
| } | ||
| }, | ||
| "required": ["wp:post_id", "title", "wp:post_content"], | ||
| "additionalProperties": false | ||
| } | ||
| } | ||
| } |
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,223 @@ | ||
| <!-- toc --> | ||
|
|
||
| # Migrating content | ||
|
|
||
| Migrating existing content into WordPress is a very common task. | ||
|
|
||
| Impex provides tooling support for migrating your content to WordPress. | ||
|
|
||
| ## Preparation | ||
|
|
||
| Impex imports data from a directory containing JSON files grouped in `chunk-\*` sub directories. | ||
|
|
||
| ``` | ||
| my-exported-website | ||
| ├── chunk-0001 | ||
| │  ├── slice-0001.json | ||
| │  ├── slice-0002.json | ||
| │  ├── slice-0003.json | ||
| │  ├── slice-0004.json | ||
| │  └── slice-0005.json | ||
| ├── chunk-0002 | ||
| │ ├── slice-0001.json | ||
| │ ├── slice-0001-wes-walker-unsplash.jpg | ||
| │ ├── slice-0002-greysen-johnson-unsplash.jpg | ||
| │ ├── slice-0002.json | ||
| │ ├── slice-0003-james-wheeler-unsplash.jpg | ||
| │ └── slice-0003.json | ||
| ... | ||
| ``` | ||
|
|
||
| > Why that _chunk-\*_ sub directory structure ? | ||
| > | ||
| > Organizing thousands of content documents and hundreds of images/videos in a single directory slows down file managers like Windows Explorer. That's the one and only reason for `chunk-\*` sub directories. | ||
| Both _chunk-\*_ sub directories and the JSON files are suffixed by a 4 digit number. | ||
|
|
||
| Impex imports slice files ordered by name. So the slices in sub directory `chunk-0001` will be imported first, then the slices in `chunk-0002` and so on. | ||
|
|
||
| Same rule for `slice-*.json` files within the same `chunk-\*` sub directory : `slice-0001.json` will be imported before `slice-0002.json` and so on. | ||
|
|
||
| > Know that import order is important. If you import content referencing images/videos in the wrong order, you will get broken links. Impex will rewrite/fix media links in the content if you **import content as first and media afterwards.** | ||
| Have a look at this [sample Impex export](https://github.com/IONOS-WordPress/cm4all-wp-impex/tree/develop/impex-cli/tests/fixtures/simple-import) provided by the Impex plugin to get a clue about a minimal working impex export containing content and referencing images. | ||
|
|
||
| ## Data files | ||
|
|
||
| `slice-*.json` files are JSON files containing data. | ||
|
|
||
| The real data is stored in the `data` property. | ||
|
|
||
| The data might be anything expressed in textual form. Beside the data itself, each `slice-*.json` file contains some json data describing the data so that Impex knows how to import. | ||
|
|
||
| An minimal slice file transporting a single Wordpress post looks like this: | ||
|
|
||
| ```json | ||
| { | ||
| "version": "1.0.0", | ||
| "type": "php", | ||
| "tag": "content-exporter", | ||
| "meta": { | ||
| "entity": "content-exporter" | ||
| }, | ||
| "data": { | ||
| "posts": [ | ||
| { | ||
| "wp:post_id": 1, | ||
| "wp:post_content": "<!-- wp:paragraph -->\n<p>Hello from first imported post !</p>\n<!-- /wp:paragraph -->", | ||
| "title": "Hello first post!" | ||
| } | ||
| ] | ||
| } | ||
| } | ||
| ``` | ||
|
|
||
| As you can see the real content is located in the `data` property. | ||
|
|
||
| Everything except the `data` property are used for versioning and content identification. | ||
|
|
||
| ### Content (aka WordPress posts/pages) | ||
|
|
||
| Content slice files wrap regular WordPress _posts_ and _pages_. | ||
|
|
||
| Content slices may also transport further content like comments, custom fields, terms, taxonomies, categories, FSE templates/template-parts, global styles and so on. But that's another story. | ||
|
|
||
| > To get a clue about the power of content slices by exporting a FSE enabled WordPress instance and inspecting the resulting `slice-_.json` files. | ||
| Below is a [JSONschema](https://json-schema.org/) describing the content slice file format. | ||
|
|
||
| Download [JSONschema](https://json-schema.org/) definition for content slices : [slice-content.json](https://github.com/IONOS-WordPress/cm4all-wp-impex/tree/develop/docs/gh-pages/src/jsonschema/slice-content.json) | ||
|
|
||
| ```json | ||
| {{#include ./jsonschema/slice-content.json}} | ||
| ``` | ||
|
|
||
| A content slice may contain any number of WordPress posts/pages/etc. | ||
|
|
||
| > When generating a content slice file, it's best to embed only a single page/post per `slice-_.json` file | ||
| Each content document is identified by a unique `wp:post_id` property. | ||
|
|
||
| The `title` property is used as the title. | ||
|
|
||
| `wp:post_content` transports the content. | ||
|
|
||
| _See the Content slice [JSONSchema definition](https://github.com/IONOS-WordPress/cm4all-wp-impex/tree/develop/docs/gh-pages/src/jsonschema/slice-content.json) for all supported properties._ | ||
|
|
||
| Since WordPress expects [block-annotated HTML](https://wordpress.com/support/wordpress-editor/blocks/) you need to transform your HTML content into [block-annotated HTML](https://wordpress.com/support/wordpress-editor/blocks/). | ||
|
|
||
| There are 2 options to do that : | ||
|
|
||
| - **The gold solution** : annotate almost every HTML tag with the matching [Gutenberg block](https://wordpress.com/support/wordpress-editor/blocks/custom-html-block/). | ||
|
|
||
| ```html | ||
| <!-- wp:paragraph --> | ||
| <p>A bit of custom html utilizing the Gutenberg html block</p> | ||
| <!-- /wp:paragraph --> | ||
|
|
||
| <!-- wp:list --> | ||
| <ul> | ||
| <li>hi</li> | ||
| <li>ho</li> | ||
| <li>howdy</li> | ||
| </ul> | ||
| <!-- /wp:list --> | ||
|
|
||
| <!-- wp:image --> | ||
| <figure class="wp-block-image"> | ||
| <img src="./greysen-johnson-unsplash.jpg" /> | ||
| <figcaption>Fly fishing</figcaption> | ||
| </figure> | ||
| <!-- /wp:image --> | ||
| ``` | ||
|
|
||
| - the quick and dirty solution : wrap the whole html content into a WordPress [Custom HTML block](https://wordpress.com/support/wordpress-editor/blocks/custom-html-block/) : | ||
|
|
||
| ```html | ||
| <!-- wp:html --> | ||
| <p>A bit of custom html utilizing the Gutenberg html block</p> | ||
| <ul> | ||
| <li>hi</li> | ||
| <li>ho</li> | ||
| <li>howdy</li> | ||
| </ul> | ||
| <figure> | ||
| <img src="./greysen-johnson-unsplash.jpg" /> | ||
| <figcaption>Fly fishing</figcaption> | ||
| </figure> | ||
| <!-- /wp:html --> | ||
| ``` | ||
|
|
||
| _Why is this solution dirty ?_ | ||
|
|
||
| _=> If you open up a page/post containing a - the quick and dirty solution : wrap the whole html content into a WordPress [Custom HTML block](https://wordpress.com/support/wordpress-editor/blocks/custom-html-block/) in the Gutenberg editor, you will see just the HTML content but its not rendered_. So the quick and dirty solution is actually a no-go from a designers perspective. | ||
|
|
||
| The HTML content must be encoded as JSON string in the slice file. See [this example content slice](https://github.com/IONOS-WordPress/cm4all-wp-impex/blob/develop/impex-cli/tests/fixtures/simple-import/chunk-0001/slice-0005.json). | ||
|
|
||
| See [Attachments (like Pictures and Videos)](#attachments-like-pictures-and-videos) for importing referenced media files. | ||
|
|
||
| ### Attachments (like Pictures and Videos) | ||
|
|
||
| Attachments a binary files like images/videos or anything else stored in the WordPress `uploads` directory. | ||
|
|
||
| Such binary data is handled a bit differently than textual - because it cannot be easily embedded into a JSON file. | ||
|
|
||
| Below is a [JSONschema](https://json-schema.org/) describing the attachment slice file format. | ||
|
|
||
| Download [JSONschema](https://json-schema.org/) definition for media files : [slice-attachment.json](https://github.com/IONOS-WordPress/cm4all-wp-impex/tree/develop/docs/gh-pages/src/jsonschema/slice-content.json) | ||
|
|
||
| ```json | ||
| {{#include ./jsonschema/slice-attachment.json}} | ||
| ``` | ||
|
|
||
| Let's say you have a reference to an image in your content : | ||
|
|
||
| ```html | ||
| <img src="./greysen-johnson-unsplash.jpg" /> | ||
| ``` | ||
|
|
||
| So you need to import the image into your WordPress instance. To do so, you need to | ||
|
|
||
| - create a `slice-*json` file (let's name it `slice-0002.json`) declaring the attachment : | ||
|
|
||
| ```json | ||
| { | ||
| "version": "1.0.0", | ||
| "type": "resource", | ||
| "tag": "attachment", | ||
| "meta": { | ||
| "entity": "attachment" | ||
| }, | ||
| "data": "./greysen-johnson-unsplash.jpg" | ||
| } | ||
| ``` | ||
|
|
||
| As you can see, there is actually only the `data` property referencing the image. Rest of the slice file is just boilerplate code. | ||
|
|
||
| - provide the image in the same chunk directory as it's slice json file and **prefixed** with the slice json file name (`slice-0002.json`) : | ||
|
|
||
| ``` | ||
| slice-0002-greysen-johnson-unsplash.jpg | ||
| ``` | ||
|
|
||
| Thats it ! If you import the slice file using Impex, the image will appear in the WordPress `uploads` directory and in the WordPress media page. If you referenced the image in your content, it will also appear in your imported pages/posts. | ||
|
|
||
| > Remember: Content slices referencing media files should **ALWAYS** be imported **before** the attachment slices. | ||
| > | ||
| > This can be achieved by naming content slicing with a lower number than the media slices or - much simpler - keeping the content slices in a lower numbered `chunk-*` directory than the attachments. | ||
| > | ||
| > See [simple-import](https://github.com/IONOS-WordPress/cm4all-wp-impex/tree/develop/impex-cli/tests/fixtures/simple-import) example for a full featured generated import at the [Impex Github page](https://github.com/IONOS-WordPress/cm4all-wp-impex). | ||
|
|
||
| ### Other data | ||
|
|
||
| Although Impex provides a simple way to import content and media, you may also want to import more advanced data like database tables or settings into WordPress. | ||
|
|
||
| Impex can import | ||
|
|
||
| - relational data like database tables | ||
|
|
||
| - key/value based settings | ||
|
|
||
| into WordPress. | ||
|
|
||
| @TODO: Add JSONSchema / examples for other data. |
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1 @@ | ||
| * |
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,91 @@ | ||
| # PHPUnit Docker Container. | ||
| FROM alpine:latest as builder | ||
| LABEL mantainer="Lars Gersmann <lars.gersmann@cm4all.com>" | ||
|
|
||
| WORKDIR /tmp | ||
|
|
||
| RUN apk --no-cache add \ | ||
| bash \ | ||
| ca-certificates \ | ||
| curl \ | ||
| git \ | ||
| php8 \ | ||
| php8-bcmath \ | ||
| php8-ctype \ | ||
| php8-curl \ | ||
| php8-dom \ | ||
| php8-exif \ | ||
| php8-fileinfo \ | ||
| php8-json \ | ||
| php8-mbstring \ | ||
| php8-pecl-mcrypt \ | ||
| php8-mysqli \ | ||
| php8-opcache \ | ||
| php8-openssl \ | ||
| php8-pcntl \ | ||
| php8-pdo \ | ||
| php8-pdo_mysql \ | ||
| php8-pdo_pgsql \ | ||
| php8-pdo_sqlite \ | ||
| php8-phar \ | ||
| php8-session \ | ||
| php8-simplexml \ | ||
| php8-soap \ | ||
| php8-tokenizer \ | ||
| php8-xdebug \ | ||
| php8-xml \ | ||
| php8-xmlreader \ | ||
| php8-xmlwriter \ | ||
| php8-zip \ | ||
| php8-zlib \ | ||
| unzip | ||
|
|
||
| # composer expects command "php" available in path | ||
| RUN ln -s /usr/bin/php8 /usr/bin/php | ||
|
|
||
| # install composer | ||
| RUN wget https://getcomposer.org/installer -O composer-setup.php && php composer-setup.php --install-dir=/usr/bin --filename=composer && rm composer-setup.php | ||
|
|
||
| # install phpunit | ||
| RUN composer require "phpunit/phpunit:^9.5" --prefer-source --no-interaction | ||
| # RUN composer require "phpunit/php-invoker" --prefer-source --no-interaction | ||
| RUN ln -s /tmp/vendor/bin/phpunit /usr/local/bin/phpunit | ||
|
|
||
| # Enable X-Debug | ||
| RUN sed -i 's/\;z/z/g' /etc/php8/conf.d/*xdebug.ini | ||
| # RUN php -m | grep -i xdebug | ||
|
|
||
| # pear support | ||
| RUN wget https://pear.php.net/go-pear.phar -O go-pear.phar && echo 'Y' | php go-pear.phar && rm go-pear.phar | ||
| # add your pear packages to be installed using --build-arg in the docker run command | ||
| ARG PEAR_PACKAGES="" | ||
| ONBUILD RUN \ | ||
| { \ | ||
| [ "${PEAR_PACKAGES}" != "" ]; \ | ||
| } || exit 0 && pear install ${PEAR_PACKAGES} | ||
|
|
||
| # see https://phpunit.readthedocs.io/en/9.5/installation.html#recommended-php-configuration | ||
| RUN echo $'memory_limit=-1\n\ | ||
| error_reporting=-1\n\ | ||
| log_errors_max_len=0\n\ | ||
| zend.assertions=1\n\ | ||
| assert.exception=1\n\ | ||
| xdebug.show_exception_trace=0\n' >> /etc/php8/php.ini | ||
|
|
||
| ##################################################################################################### | ||
|
|
||
| FROM alpine:latest | ||
| # simple trick to get rid of intermediate layers | ||
| # https://stackoverflow.com/questions/56117261/how-to-merge-dockers-layers-of-image-and-slim-down-the-image-file | ||
| COPY --from=builder / / | ||
|
|
||
| VOLUME ["/workdir"] | ||
| WORKDIR /workdir/tests | ||
|
|
||
| # add a entrypoint script to enable CTRL-C abortion in terminal | ||
| # (see https://stackoverflow.com/a/57526365/1554103) | ||
| # RUN echo "#!/bin/bash" > /usr/local/bin/docker-entrypoint.sh && \ | ||
| # echo '$@' >> /usr/local/bin/docker-entrypoint.sh && \ | ||
| # chmod a+x /usr/local/bin/docker-entrypoint.sh | ||
|
|
||
| # ENTRYPOINT ["/usr/local/bin/docker-entrypoint.sh"] |
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,25 @@ | ||
| # About | ||
|
|
||
| a tiny (alpine based) docker image for phpunit testing. | ||
|
|
||
| ## Features | ||
|
|
||
| - php 8 | ||
|
|
||
| - including xdebug support | ||
|
|
||
| - phpunit 9.5 | ||
|
|
||
| # Development | ||
|
|
||
| build : `DOCKER_BUILDKIT=1 docker build -t cm4all-wp-impex/impex-cli-phpunit .` | ||
|
|
||
| - (optional) you can add `--build-arg PEAR_PACKAGES="<space-separated-list-of-pear-packages>"` to auto install pear packages into the image | ||
|
|
||
| jump into : `docker run -ti --rm cm4all-wp-impex/impex-cli-phpunit bash` | ||
|
|
||
| php.ini : `/etc/php8/php.ini` | ||
|
|
||
| # Usage | ||
|
|
||
| `docker run --add-host=host.docker.internal:host-gateway -it -v $(pwd)/..:/workdir --rm cm4all-wp-impex/impex-cli-phpunit phpunit .` |
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,49 @@ | ||
| <?php | ||
|
|
||
| namespace cm4all\wp\impex\tests\phpunit; | ||
|
|
||
| use PHPUnit\Framework\TestCase; | ||
|
|
||
| require_once __DIR__ . '/../impex-cli.php'; | ||
|
|
||
| function impex_cli($operation, ...$args): array | ||
| { | ||
| $retval = [ | ||
| 'stderr' => '', | ||
| 'stdout' => '', | ||
| 'exit_code' => 0, | ||
| ]; | ||
|
|
||
| ob_start(); | ||
|
|
||
| try { | ||
| \cm4all\wp\impex\cli\main([ | ||
| realpath(__DIR__ . '/../impex-cli/impex-cli.php'), | ||
| $operation, | ||
| '-rest-url=http://host.docker.internal:8889/wp-json', | ||
| '-username=admin', | ||
| '-password=password', | ||
| ...$args, | ||
| ]); | ||
| } catch (\cm4all\wp\impex\cli\DieException $ex) { | ||
| $retval['stderr'] = $ex->getMessage(); | ||
| $retval['exit_code'] = $ex->getCode(); | ||
| } finally { | ||
| $retval['stdout'] = ob_get_clean(); | ||
| } | ||
|
|
||
| return $retval; | ||
| } | ||
|
|
||
| abstract class AbstractImpexCLITestCase extends TestCase | ||
| { | ||
| function setUp(): void | ||
| { | ||
| parent::setUp(); | ||
| } | ||
|
|
||
| function tearDown(): void | ||
| { | ||
| parent::tearDown(); | ||
| } | ||
| } |
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,17 @@ | ||
| { | ||
| "version": "1.0.0", | ||
| "type": "php", | ||
| "tag": "content-exporter", | ||
| "meta": { | ||
| "entity": "content-exporter" | ||
| }, | ||
| "data": { | ||
| "posts": [ | ||
| { | ||
| "wp:post_id": 1, | ||
| "wp:post_content": "<!-- wp:paragraph -->\n<p>Hello from first imported post !</p>\n<!-- /wp:paragraph -->", | ||
| "title": "Hello first post!" | ||
| } | ||
| ] | ||
| } | ||
| } |
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,20 @@ | ||
| { | ||
| "version": "1.0.0", | ||
| "type": "php", | ||
| "tag": "content-exporter", | ||
| "meta": { | ||
| "entity": "content-exporter" | ||
| }, | ||
| "data": { | ||
| "posts": [ | ||
| { | ||
| "wp:status": "publish", | ||
| "wp:post_type": "page", | ||
| "wp:post_name": "hello-world", | ||
| "wp:post_id": 2, | ||
| "wp:post_content": "<!-- wp:paragraph -->\n<p>Hello from import !</p>\n<!-- /wp:paragraph -->", | ||
| "title": "Hello world!" | ||
| } | ||
| ] | ||
| } | ||
| } |
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,20 @@ | ||
| { | ||
| "version": "1.0.0", | ||
| "type": "php", | ||
| "tag": "content-exporter", | ||
| "meta": { | ||
| "entity": "content-exporter" | ||
| }, | ||
| "data": { | ||
| "posts": [ | ||
| { | ||
| "wp:status": "publish", | ||
| "wp:post_type": "page", | ||
| "wp:post_name": "page-with-image", | ||
| "wp:post_id": 3, | ||
| "wp:post_content": "<!-- wp:paragraph -->\n<p>Hello world</p>\n<!-- /wp:paragraph -->\n<!-- wp:image --><figure class=\"wp-block-image\"><img src=\"./wes-walker-unsplash.jpg\"/></figure><!-- /wp:image -->", | ||
| "title": "A page with an image block" | ||
| } | ||
| ] | ||
| } | ||
| } |
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,20 @@ | ||
| { | ||
| "version": "1.0.0", | ||
| "type": "php", | ||
| "tag": "content-exporter", | ||
| "meta": { | ||
| "entity": "content-exporter" | ||
| }, | ||
| "data": { | ||
| "posts": [ | ||
| { | ||
| "wp:status": "publish", | ||
| "wp:post_type": "page", | ||
| "wp:post_name": "page-with-gallery-multiple-images", | ||
| "wp:post_id": 4, | ||
| "wp:post_content": "<!-- wp:paragraph -->\n<p>Hello world</p>\n<!-- /wp:paragraph -->\n<!-- wp:gallery -->\n<figure class=\"wp-block-gallery has-nested-images columns-default is-cropped\">\n <!-- wp:image -->\n <figure class=\"wp-block-image\"><img src=\"./james-wheeler-unsplash.jpg\"/></figure>\n <!-- /wp:image -->\n\n <!-- wp:image -->\n <figure class=\"wp-block-image\"><img src=\"./greysen-johnson-unsplash.jpg\"/></figure>\n <!-- /wp:image -->\n\n <!-- wp:image -->\n <figure class=\"wp-block-image\"><img src=\"./wes-walker-unsplash.jpg\"/></figure>\n <!-- /wp:image -->\n</figure>\n<!-- /wp:gallery -->", | ||
| "title": "A page with gallery block." | ||
| } | ||
| ] | ||
| } | ||
| } |
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,20 @@ | ||
| { | ||
| "version": "1.0.0", | ||
| "type": "php", | ||
| "tag": "content-exporter", | ||
| "meta": { | ||
| "entity": "content-exporter" | ||
| }, | ||
| "data": { | ||
| "posts": [ | ||
| { | ||
| "wp:status": "publish", | ||
| "wp:post_type": "page", | ||
| "wp:post_name": "page-with-custom-html-including-media", | ||
| "wp:post_id": 5, | ||
| "wp:post_content": "<!-- wp:paragraph -->\n<p>Hello world</p>\n<!-- /wp:paragraph -->\n\n<!-- wp:html -->\n<p>A bit of custom html utilizing the Gutenberg html block</p>\n<ul>\n <li>hi</li>\n <li>ho</li>\n <li>howdy</li>\n</ul>\n<figure class=\"wp-block-image\">\n<img src=\"http://localhost:8889/wp-content/uploads/2022/03/greysen-johnson-unsplash.jpg\" alt=\"\"> <figcaption>Fly fishing</figcaption>\n</figure>\n<!-- /wp:html -->", | ||
| "title": "A page using Gutenberg HTML block." | ||
| } | ||
| ] | ||
| } | ||
| } |
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,9 @@ | ||
| { | ||
| "version": "1.0.0", | ||
| "type": "resource", | ||
| "tag": "attachment", | ||
| "meta": { | ||
| "entity": "attachment" | ||
| }, | ||
| "data": "./wes-walker-unsplash.jpg" | ||
| } |
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,9 @@ | ||
| { | ||
| "version": "1.0.0", | ||
| "type": "resource", | ||
| "tag": "attachment", | ||
| "meta": { | ||
| "entity": "attachment" | ||
| }, | ||
| "data": "./greysen-johnson-unsplash.jpg" | ||
| } |
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,9 @@ | ||
| { | ||
| "version": "1.0.0", | ||
| "type": "resource", | ||
| "tag": "attachment", | ||
| "meta": { | ||
| "entity": "attachment" | ||
| }, | ||
| "data": "./james-wheeler-unsplash.jpg" | ||
| } |
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,21 @@ | ||
| <phpunit | ||
| backupGlobals="false" | ||
| colors="true" | ||
| convertErrorsToExceptions="true" | ||
| convertNoticesToExceptions="true" | ||
| convertWarningsToExceptions="true" | ||
| cacheResult="false" | ||
| > | ||
| <testsuites> | ||
| <testsuite name="impex-cli"> | ||
| <directory | ||
| phpVersion="8.0.0" | ||
| phpVersionOperator=">=" | ||
| prefix="test-" | ||
| suffix=".php" | ||
| > | ||
| ./ | ||
| </directory> | ||
| </testsuite> | ||
| </testsuites> | ||
| </phpunit> |
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,25 @@ | ||
| <?php | ||
|
|
||
| use cm4all\wp\impex\tests\phpunit\AbstractImpexCLITestCase; | ||
|
|
||
| use function cm4all\wp\impex\tests\phpunit\impex_cli; | ||
|
|
||
| require_once __DIR__ . "/abstract-impex-cli-testcase.php"; | ||
|
|
||
| final class ImportProfileTest extends AbstractImpexCLITestCase | ||
| { | ||
| function testImportProfiles() | ||
| { | ||
| // curl -v 'http://host.docker.internal:8889/wp-json/cm4all-wp-impex/v1/export/profile' -H 'accept: application/json' -H 'authorization: Basic YWRtaW46cGFzc3dvcmQ=' | ||
|
|
||
| $result = impex_cli( | ||
| 'import-profile', | ||
| // '-CURLOPT_VERBOSE', | ||
| // '-verbose', | ||
| // __DIR__ . '/fixtures/impex-cli/simple-snapshot', | ||
| ); | ||
|
|
||
| $this->assertEquals('', $result['stderr'], 'stderr should be empty'); | ||
| $this->assertEquals(0, $result['exit_code'], 'should succeed'); | ||
| } | ||
| } |
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,43 @@ | ||
| <?php | ||
|
|
||
| use cm4all\wp\impex\tests\phpunit\AbstractImpexCLITestCase; | ||
|
|
||
| use function cm4all\wp\impex\tests\phpunit\impex_cli; | ||
|
|
||
| require_once __DIR__ . "/abstract-impex-cli-testcase.php"; | ||
| final class ImportTest extends AbstractImpexCLITestCase | ||
| { | ||
| function testInvalidOptions() | ||
| { | ||
| $result = impex_cli( | ||
| '-overwrite', | ||
| '/tmp/test-export.zip', | ||
| ); | ||
|
|
||
| $this->assertEquals(1, $result['exit_code'], 'should fail because of misplaced options/arguments'); | ||
| } | ||
|
|
||
| function testImportEmptySnapshotDirectory() | ||
| { | ||
| $result = impex_cli( | ||
| 'import', | ||
| '-overwrite', | ||
| '-profile=all', | ||
| __DIR__ . '/fixtures/empty-snapshot', | ||
| ); | ||
|
|
||
| $this->assertEquals(0, $result['exit_code'], 'should succeed'); | ||
| } | ||
|
|
||
| function testSimpleImport() | ||
| { | ||
| $result = impex_cli( | ||
| 'import', | ||
| '-overwrite', | ||
| '-profile=all', | ||
| __DIR__ . '/fixtures/simple-import', | ||
| ); | ||
|
|
||
| $this->assertEquals(0, $result['exit_code'], 'should succeed'); | ||
| } | ||
| } |
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -1,6 +1,6 @@ | ||
| { | ||
| "name": "cm4all-wp-impex", | ||
| "version": "1.2.1", | ||
| "scripts": { | ||
| "dev": "make dev", | ||
| "build": "make", | ||
|
|
||
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,200 @@ | ||
| { | ||
| "tag": "content-exporter", | ||
| "version": "1.0.0", | ||
| "meta": { | ||
| "entity": "content-exporter", | ||
| "options": [] | ||
| }, | ||
| "data": { | ||
| "wp:bloginfo_title": "cm4all-wp-impex", | ||
| "wp:bloginfo_url": "http://localhost:8888", | ||
| "wp:bloginfo_description": "Just another WordPress site", | ||
| "wp:bloginfo_language": "en-US", | ||
| "wp:bloginfo_rss_url": "http://localhost:8888", | ||
| "authors": [ | ||
| { | ||
| "wp:author_id": 0, | ||
| "wp:author_login": null, | ||
| "wp:author_email": null, | ||
| "wp:author_display_name": null, | ||
| "wp:author_first_name": null, | ||
| "wp:author_last_name": null | ||
| }, | ||
| { | ||
| "wp:author_id": 1, | ||
| "wp:author_login": "admin", | ||
| "wp:author_email": "wordpress@example.com", | ||
| "wp:author_display_name": "admin", | ||
| "wp:author_first_name": "", | ||
| "wp:author_last_name": "" | ||
| } | ||
| ], | ||
| "taxonomies": [], | ||
| "categories": { | ||
| "1": { | ||
| "wp:term_id": 1, | ||
| "wp:term_slug": "uncategorized", | ||
| "wp:term_parent": "", | ||
| "wp:term_name": "Uncategorized", | ||
| "wp:term_description": "", | ||
| "wp:term_meta": [] | ||
| } | ||
| }, | ||
| "tags": [], | ||
| "terms": [ | ||
| { | ||
| "wp:term_id": 1, | ||
| "wp:term_taxonomy": "category", | ||
| "wp:term_slug": "uncategorized", | ||
| "wp:term_parent": "", | ||
| "wp:term_name": "Uncategorized", | ||
| "wp:term_description": "", | ||
| "wp:term_meta": [] | ||
| }, | ||
| { | ||
| "wp:term_id": 3, | ||
| "wp:term_taxonomy": "wp_theme", | ||
| "wp:term_slug": "trinity-core", | ||
| "wp:term_parent": "", | ||
| "wp:term_name": "trinity-core", | ||
| "wp:term_description": "", | ||
| "wp:term_meta": [] | ||
| } | ||
| ], | ||
| "posts": [ | ||
| { | ||
| "title": "Header Vorlage", | ||
| "link": null, | ||
| "pubDate": false, | ||
| "dc:creator": "", | ||
| "guid": null, | ||
| "guid_isPermaLink": false, | ||
| "description": null, | ||
| "wp:post_content": "<!-- wp:cover {\"url\":\"/wp-content/themes/trinity-core/reusable-blocks/images/content_0002_david-gavi-Ijx8OxvKrgM-unsplash.jpg\",\"customOverlayColor\":\"rgba(0,0, 0, 1)\",\"focalPoint\":{\"x\":\"0.54\",\"y\":\"0.85\"},\"minHeight\":600,\"minHeightUnit\":\"px\",\"align\":\"full\",\"cm4allBlockId\":\"4accb986-dd24-4029-bfb3-ee9bfca557a5\"} -->\n<div class=\"wp-block-cover alignfull has-background-dim\" style=\"min-height:600px\"><img class=\"wp-block-cover__image-background \" alt=\"\" src=\"/wp-content/themes/trinity-core/reusable-blocks/images/content_0002_david-gavi-Ijx8OxvKrgM-unsplash.jpg\" style=\"object-position:54% 85%\" data-object-fit=\"cover\" data-object-position=\"54% 85%\" /><div class=\"wp-block-cover__inner-container\"><!-- wp:group {\"align\":\"wide\",\"className\":\"is-style-cm4all-theme-blocku002du002dshrink-center\",\"cm4allBlockId\":\"f9f61c5f-5133-40cf-b663-c9a9c30de4e2\"} -->\n<div class=\"wp-block-group alignwide is-style-cm4all-theme-block--shrink-center\"><!-- wp:heading {\"textAlign\":\"center\",\"level\":1,\"style\":{\"color\":{\"text\":\"rgba(255,255, 255, 1)\"}},\"className\":\"\",\"cm4allBlockId\":\"b6b44337-ebaa-4058-8d6c-cdbc7d11ab28\"} -->\n<h1 class=\"has-text-align-center has-text-color\" style=\"color:rgba(255,255, 255, 1)\">Willkommen bei<br>[Unternehmen]</h1>\n<!-- /wp:heading -->\n\n<!-- wp:paragraph {\"align\":\"center\",\"style\":{\"color\":{\"text\":\"rgba(255,255, 255, 1)\"}},\"className\":\"\",\"cm4allBlockId\":\"fd614a2c-0500-4e6c-847c-10855869f1f0\"} -->\n<p class=\"has-text-align-center has-text-color\" style=\"color:rgba(255,255, 255, 1)\">Lorem ipsum dolor sit amet, consectetuer adipiscing elit. Aenean commodo ligula eget dolor. Aenean massa. Cum sociis natoque penatibus et magnis dis parturient montes, nascetur ridiculus mus.</p>\n<!-- /wp:paragraph -->\n\n<!-- wp:buttons {\"contentJustification\":\"center\",\"className\":\"\",\"cm4allBlockId\":\"e4b5b644-a252-440a-99c7-919d72037ad3\"} -->\n<div class=\"wp-block-buttons is-content-justification-center\"><!-- wp:button {\"className\":\"is-style-outline\",\"cm4allBlockId\":\"bd5bfa00-38a4-4901-b0c0-e5bd61bac962\"} -->\n<div class=\"wp-block-button is-style-outline\"><a class=\"wp-block-button__link\">Jetzt kontaktieren</a></div>\n<!-- /wp:button --></div>\n<!-- /wp:buttons --></div>\n<!-- /wp:group --></div></div>\n<!-- /wp:cover -->", | ||
| "wp:post_excerpt": "", | ||
| "wp:post_id": 4, | ||
| "wp:post_date": "2022-03-08 08:06:47", | ||
| "wp:post_date_gmt": "2022-03-08 08:06:47", | ||
| "wp:post_modified_gmt": "2022-03-08 08:06:47", | ||
| "wp:comment_status": "closed", | ||
| "wp:ping_status": "closed", | ||
| "wp:post_name": "header-vorlage", | ||
| "wp:status": "publish", | ||
| "wp:post_parent": 0, | ||
| "wp:menu_order": 0, | ||
| "wp:post_type": "wp_block", | ||
| "wp:post_password": "", | ||
| "wp:is_sticky": 0, | ||
| "wp:attachment_url": null, | ||
| "taxonomy_terms": [], | ||
| "meta": [], | ||
| "comments": [] | ||
| }, | ||
| { | ||
| "title": "Footer Vorlage", | ||
| "link": null, | ||
| "pubDate": false, | ||
| "dc:creator": "", | ||
| "guid": null, | ||
| "guid_isPermaLink": false, | ||
| "description": null, | ||
| "wp:post_content": "<!-- wp:group {\"align\":\"full\",\"style\":{\"spacing\":{\"padding\":{\"top\":\"80px\",\"bottom\":\"80px\"}}},\"backgroundColor\":\"trinity-theme-secondary-contrast-variant\",\"layout\":{\"wideSize\":\"px\"},\"cm4allBlockId\":\"2fdfc9fd-cceb-42cc-8cca-2a59fbbb682c\"} -->\n<div class=\"wp-block-group alignfull has-trinity-theme-secondary-contrast-variant-background-color has-background\" style=\"padding-top:80px;padding-bottom:80px\"><!-- wp:columns {\"align\":\"wide\",\"cm4allBlockId\":\"82bde859-29a4-4d42-85db-0e289580a623\"} -->\n<div class=\"wp-block-columns alignwide\"><!-- wp:column {\"cm4allBlockId\":\"89db2977-3e48-4428-bc36-76f732bd0b5b\"} -->\n<div class=\"wp-block-column\"><!-- wp:group {\"style\":{\"spacing\":{\"padding\":{\"bottom\":\"20px\"}}},\"cm4allBlockId\":\"0eb1eaa6-0f66-4ba0-8b3c-78d81a3f0ca1\"} -->\n<div class=\"wp-block-group\" style=\"padding-bottom:20px\"><!-- wp:heading {\"level\":3,\"style\":{\"typography\":{\"fontSize\":\"53px\"},\"color\":{\"text\":\"rgba(255,255, 255, 1)\"}},\"className\":\"\",\"cm4allBlockId\":\"2e5f3d2c-3a9e-4d50-bd45-13065fd6ba38\"} -->\n<h3 class=\"has-text-color\" style=\"color:rgba(255,255, 255, 1);font-size:53px\">Wir freuen<br>uns auf Sie! </h3>\n<!-- /wp:heading --></div>\n<!-- /wp:group --></div>\n<!-- /wp:column -->\n\n<!-- wp:column {\"cm4allBlockId\":\"e91bf9e1-5c80-402e-a2b5-2d3960f06565\"} -->\n<div class=\"wp-block-column\"><!-- wp:group {\"style\":{\"spacing\":{\"padding\":{\"bottom\":\"20px\"}}},\"cm4allBlockId\":\"0976f56a-d803-4b6f-9b26-778e3e4c7263\"} -->\n<div class=\"wp-block-group\" style=\"padding-bottom:20px\"><!-- wp:heading {\"level\":4,\"style\":{\"color\":{\"text\":\"rgba(255,255, 255, 1)\"}},\"className\":\"\",\"cm4allBlockId\":\"0f22ba45-55fd-4d7b-ae02-136ad33eddb4\"} -->\n<h4 class=\"has-text-color\" style=\"color:rgba(255,255, 255, 1)\">IHR Unternehmen</h4>\n<!-- /wp:heading -->\n\n<!-- wp:paragraph {\"style\":{\"color\":{\"text\":\"rgba(255,255, 255, 1)\"}},\"className\":\"\",\"cm4allBlockId\":\"b5936153-094a-494d-97fa-af6fefa3a6b5\"} -->\n<p class=\"has-text-color\" style=\"color:rgba(255,255, 255, 1)\">Inhaber: Max Mustermann<br>[Musterstraße 654]<br>[12345 Musterstadt]</p>\n<!-- /wp:paragraph --></div>\n<!-- /wp:group --></div>\n<!-- /wp:column -->\n\n<!-- wp:column {\"cm4allBlockId\":\"ee0ae707-f0cf-45aa-8b60-f381f918635e\"} -->\n<div class=\"wp-block-column\"><!-- wp:group {\"style\":{\"spacing\":{\"padding\":{\"bottom\":\"20px\"}}},\"cm4allBlockId\":\"363034b5-1348-4c42-b902-21a151520056\"} -->\n<div class=\"wp-block-group\" style=\"padding-bottom:20px\"><!-- wp:heading {\"level\":4,\"style\":{\"color\":{\"text\":\"rgba(255,255, 255, 1)\"}},\"className\":\"\",\"cm4allBlockId\":\"8bc1d89a-58fb-4791-a488-76df05f93532\"} -->\n<h4 class=\"has-text-color\" style=\"color:rgba(255,255, 255, 1)\">Kontakt</h4>\n<!-- /wp:heading -->\n\n<!-- wp:paragraph {\"style\":{\"color\":{\"text\":\"rgba(255,255, 255, 1)\"}},\"className\":\"\",\"cm4allBlockId\":\"c3279e95-3f56-42dd-824d-738fd32521ae\"} -->\n<p class=\"has-text-color\" style=\"color:rgba(255,255, 255, 1)\">Tel.: [+49 (0) 123 45 67 89]<br>Fax: [+49 (0) 123 45 67 10]<br>E-Mail: [info@musterfirma.de]</p>\n<!-- /wp:paragraph --></div>\n<!-- /wp:group --></div>\n<!-- /wp:column -->\n\n<!-- wp:column {\"cm4allBlockId\":\"b55a91ae-0aff-47c1-a164-d371236d29e7\"} -->\n<div class=\"wp-block-column\"><!-- wp:group {\"style\":{\"spacing\":{\"padding\":{\"bottom\":\"20px\"}}},\"cm4allBlockId\":\"79f52c29-43c2-4bf9-b54e-633fe92a4af6\"} -->\n<div class=\"wp-block-group\" style=\"padding-bottom:20px\"><!-- wp:heading {\"level\":4,\"style\":{\"color\":{\"text\":\"rgba(255,255, 255, 1)\"}},\"className\":\"\",\"cm4allBlockId\":\"f6dce74e-6cdd-4e99-ac7e-7e97bd2c12d5\"} -->\n<h4 class=\"has-text-color\" style=\"color:rgba(255,255, 255, 1)\">Weitere Links</h4>\n<!-- /wp:heading -->\n\n<!-- wp:paragraph {\"style\":{\"color\":{\"text\":\"rgba(255,255, 255, 1)\"}},\"className\":\"\",\"cm4allBlockId\":\"26ce4fbf-3aae-461c-9aa1-d4ef23aa46dd\"} -->\n<p class=\"has-text-color\" style=\"color:rgba(255,255, 255, 1)\">> <a href=\"#\">Impressum</a><br>> <a href=\"#\">Datenschutz</a></p>\n<!-- /wp:paragraph --></div>\n<!-- /wp:group --></div>\n<!-- /wp:column --></div>\n<!-- /wp:columns --></div>\n<!-- /wp:group -->", | ||
| "wp:post_excerpt": "", | ||
| "wp:post_id": 5, | ||
| "wp:post_date": "2022-03-08 08:06:47", | ||
| "wp:post_date_gmt": "2022-03-08 08:06:47", | ||
| "wp:post_modified_gmt": "2022-03-08 08:06:47", | ||
| "wp:comment_status": "closed", | ||
| "wp:ping_status": "closed", | ||
| "wp:post_name": "footer-vorlage", | ||
| "wp:status": "publish", | ||
| "wp:post_parent": 0, | ||
| "wp:menu_order": 0, | ||
| "wp:post_type": "wp_block", | ||
| "wp:post_password": "", | ||
| "wp:is_sticky": 0, | ||
| "wp:attachment_url": null, | ||
| "taxonomy_terms": [], | ||
| "meta": [], | ||
| "comments": [] | ||
| }, | ||
| { | ||
| "title": "my-page", | ||
| "link": null, | ||
| "pubDate": false, | ||
| "dc:creator": "admin", | ||
| "guid": null, | ||
| "guid_isPermaLink": false, | ||
| "description": null, | ||
| "wp:post_content": "<!-- wp:paragraph {\"className\":\"\",\"cm4allBlockId\":\"38c1404f-05ac-4a8a-8ef5-d04499b0c5ae\"} -->\n<p>This is just a </p>\n<!-- /wp:paragraph -->\n\n<!-- wp:paragraph {\"className\":\"\",\"cm4allBlockId\":\"9c46ca06-bd0a-4567-9ba9-2c0b50873622\"} -->\n<p>multiline paragraph</p>\n<!-- /wp:paragraph -->\n\n<!-- wp:image {\"id\":160,\"sizeSlug\":\"full\",\"linkDestination\":\"none\",\"cm4allBlockId\":\"6c7fe1df-e801-4ed4-952f-ac82561a1f7a\"} -->\n<figure class=\"wp-block-image size-full\"><img src=\"http://localhost:8888/wp-content/uploads/2022/03/angeln.jpg\" alt=\"\" class=\"wp-image-160\"/><figcaption>Fishing is a nice hobby !</figcaption></figure>\n<!-- /wp:image -->", | ||
| "wp:post_excerpt": "", | ||
| "wp:post_id": 161, | ||
| "wp:post_date": "2022-03-08 11:29:46", | ||
| "wp:post_date_gmt": "2022-03-08 11:29:46", | ||
| "wp:post_modified_gmt": "2022-03-08 11:29:47", | ||
| "wp:comment_status": "closed", | ||
| "wp:ping_status": "closed", | ||
| "wp:post_name": "my-page", | ||
| "wp:status": "publish", | ||
| "wp:post_parent": 0, | ||
| "wp:menu_order": 0, | ||
| "wp:post_type": "page", | ||
| "wp:post_password": "", | ||
| "wp:is_sticky": 0, | ||
| "wp:attachment_url": null, | ||
| "taxonomy_terms": [], | ||
| "meta": [ | ||
| { | ||
| "wp:term_meta_key": "_edit_lock", | ||
| "wp:term_meta_value": "1646738987:1" | ||
| }, | ||
| { | ||
| "wp:term_meta_key": "_edit_last", | ||
| "wp:term_meta_value": "1" | ||
| }, | ||
| { | ||
| "wp:term_meta_key": "cmplz_hide_cookiebanner", | ||
| "wp:term_meta_value": "" | ||
| } | ||
| ], | ||
| "comments": [] | ||
| }, | ||
| { | ||
| "title": "Custom Styles", | ||
| "link": null, | ||
| "pubDate": false, | ||
| "dc:creator": "admin", | ||
| "guid": null, | ||
| "guid_isPermaLink": false, | ||
| "description": null, | ||
| "wp:post_content": "{\"version\": 2, \"isGlobalStylesUserThemeJSON\": true }", | ||
| "wp:post_excerpt": "", | ||
| "wp:post_id": 162, | ||
| "wp:post_date": "2022-03-08 11:28:31", | ||
| "wp:post_date_gmt": "2022-03-08 11:28:31", | ||
| "wp:post_modified_gmt": "2022-03-08 11:28:31", | ||
| "wp:comment_status": "closed", | ||
| "wp:ping_status": "closed", | ||
| "wp:post_name": "wp-global-styles-trinity-core", | ||
| "wp:status": "publish", | ||
| "wp:post_parent": 0, | ||
| "wp:menu_order": 0, | ||
| "wp:post_type": "wp_global_styles", | ||
| "wp:post_password": "", | ||
| "wp:is_sticky": 0, | ||
| "wp:attachment_url": null, | ||
| "taxonomy_terms": [ | ||
| { | ||
| "wp:term_taxonomy": "wp_theme", | ||
| "wp:term_slug": "trinity-core", | ||
| "wp:term_name": "trinity-core" | ||
| } | ||
| ], | ||
| "meta": [], | ||
| "comments": [] | ||
| } | ||
| ] | ||
| }, | ||
| "type": "php", | ||
| "date": "2022-03-08 11:29:55 +0000" | ||
| } |
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,38 @@ | ||
| { | ||
| "tag": "attachment", | ||
| "version": "1.0.0", | ||
| "type": "resource", | ||
| "meta": { | ||
| "name": "angeln", | ||
| "entity": "attachment", | ||
| "options": [], | ||
| "data": { | ||
| "ID": 160, | ||
| "post_author": "1", | ||
| "post_date": "2022-03-08 11:28:26", | ||
| "post_date_gmt": "2022-03-08 11:28:26", | ||
| "post_content": "", | ||
| "post_title": "angeln", | ||
| "post_excerpt": "", | ||
| "post_status": "inherit", | ||
| "comment_status": "open", | ||
| "ping_status": "closed", | ||
| "post_password": "", | ||
| "post_name": "angeln", | ||
| "to_ping": "", | ||
| "pinged": "", | ||
| "post_modified": "2022-03-08 11:28:26", | ||
| "post_modified_gmt": "2022-03-08 11:28:26", | ||
| "post_content_filtered": "", | ||
| "post_parent": 0, | ||
| "guid": "http://localhost:8888/wp-content/uploads/2022/03/angeln.jpg", | ||
| "menu_order": 0, | ||
| "post_type": "attachment", | ||
| "post_mime_type": "image/jpeg", | ||
| "comment_count": "0", | ||
| "filter": "raw" | ||
| } | ||
| }, | ||
| "data": "2022/03/angeln.jpg", | ||
| "date": "2022-03-08 11:29:55 +0000" | ||
| } |