Skip to content

Commit f3fe08d

Browse files
authored
Merge branch 'trunk' into add/wp-static-asset-zip
2 parents 1feb41a + abf5a41 commit f3fe08d

File tree

181 files changed

+4619
-2553
lines changed

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

181 files changed

+4619
-2553
lines changed

lerna.json

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
{
22
"$schema": "node_modules/lerna/schemas/lerna-schema.json",
3+
"version": "0.9.8",
34
"useWorkspaces": true,
4-
"version": "0.9.2",
55
"useNx": true
66
}

package-lock.json

Lines changed: 1091 additions & 836 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

package.json

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -14,6 +14,7 @@
1414
"format:uncommitted": "nx format --fix --parallel --uncommitted",
1515
"lint": "nx run-many --all --target=lint",
1616
"prepublishOnly": "npm run build",
17+
"mindmap": "cd packages/meta/src/mindmap/v2 && php -S 127.0.0.1:5269",
1718
"preview": "nx preview playground-website",
1819
"recompile:php:web": "nx recompile-php:light:all php-wasm-web && nx recompile-php:kitchen-sink:all php-wasm-web ",
1920
"recompile:php:web:light": "nx recompile-php:light:all php-wasm-web ",

packages/docs/site/docs/09-blueprints-api/03-data-format.md

Lines changed: 72 additions & 20 deletions
Original file line numberDiff line numberDiff line change
@@ -3,15 +3,11 @@ sidebar_position: 1
33
title: Blueprint data Format
44
---
55

6-
# Blueprint data Format
6+
# Blueprint data format
77

8-
A Blueprint can contain the following properties:
8+
A Blueprint JSON file can have many different properties that will be used to define your Playground instance. The most important properties are detailed below.
99

10-
- landingPage (string): The URL to navigate to after the Blueprint has been run.
11-
- [preferredVersions](#preferred-versions): The preferred PHP and WordPress versions to use.
12-
- [steps](./05-steps.md): The steps to run.
13-
14-
Here's a Blueprint that uses all of them:
10+
Here's an example that uses many of them:
1511

1612
import BlueprintExample from '@site/src/components/Blueprints/BlueprintExample.mdx';
1713

@@ -34,34 +30,90 @@ import BlueprintExample from '@site/src/components/Blueprints/BlueprintExample.m
3430
]
3531
}} />
3632

37-
## JSON Schema
33+
## JSON schema
3834

39-
JSON files can be tedious to write and easy to get wrong. To help with that, Playground provides a [JSON schema](https://playground.wordpress.net/blueprint-schema.json) file that you can use to get autocompletion and validation in your editor:
35+
JSON files can be tedious to write and easy to get wrong. To help with that, Playground provides a [JSON schema](https://playground.wordpress.net/blueprint-schema.json) file that you can use to get auto-completion and validation in your editor. Just set the `$schema` property to the following:
4036

4137
```js
4238
{
4339
"$schema": "https://playground.wordpress.net/blueprint-schema.json",
44-
"landingPage": "/wp-admin/",
45-
// ...
4640
}
4741
```
4842

49-
## Preferred Versions
43+
## Landing page
5044

51-
The `preferredVersions` property, unsurprisingly, declares the preferred of PHP and WordPress versions to use. It can contain the following properties:
45+
The `landingPage` property tells Playground which URL to navigate to after the Blueprint has been run. This is a great tool, especially when creating theme or plugin demos. Often, you will want to start Playground in the Site Editor or have a specific post open in the Post Editor. Make sure you use a relative path.
5246

53-
- `php` (string): The preferred PHP version to use. Defaults to "latest". Only accepts major versions, like "7.4" or "8.0". Minor versions like "7.4.1" are not supported.
54-
- `wp` (string): Loads the specified WordPress version. Supported values: The last three major WordPress versions—minor versions, like `6.5.1`, are not supported. As of April 4, 2024, that's `6.3`, `6.4`, `6.5`. You can also use these values: `latest` (default), `nightly`, or `beta`.
47+
```js
48+
{
49+
"landingPage": "/wp-admin/site-editor.php",
50+
}
51+
```
52+
53+
## Preferred versions
54+
55+
The `preferredVersions` property declares your preferred PHP and WordPress versions. It can contain the following properties:
56+
57+
- `php` (string): Loads the specified PHP version. Accepts `7.0`, `7.1`, `7.2`, `7.3`, `7.4`, `8.0`, `8.1`, `8.2`, `8.3`, or `latest`. Minor versions like `7.4.1` are not supported.
58+
- `wp` (string): Loads the specified WordPress version. Accepts the last four major WordPress versions. As of June 1, 2024, that's `6.2`, `6.3`, `6.4`, or `6.5`. You can also use the generic values `latest`, `nightly`, or `beta`.
59+
60+
```js
61+
{
62+
"preferredVersions": {
63+
"php": "8.0",
64+
"wp": "6.5"
65+
},
66+
}
67+
```
5568

5669
## PHP extensions
5770

58-
The `phpExtensionBundles` property is an array of PHP extension bundles to load. The following bundles are supported:
71+
The `phpExtensionBundles` property is an array of PHP extension bundles that should be loaded. The following bundles are supported:
5972

60-
- `light`: Default choice. Saves 6MB of downloads, loads none of the extensions below.
61-
- `kitchen-sink`: Installs [`gd`](https://www.php.net/manual/en/book.image.php), [`mbstring`](https://www.php.net/manual/en/mbstring.installation.php), [`iconv`](https://www.php.net/manual/en/function.iconv.php), [`openssl`](https://www.php.net/manual/en/book.openssl.php), [`libxml`](https://www.php.net/manual/en/book.libxml.php), [`xml`](https://www.php.net/manual/en/xml.installation.php), [`dom`](https://www.php.net/manual/en/intro.dom.php), [`simplexml`](https://www.php.net/manual/en/book.simplexml.php), [`xmlreader`](https://www.php.net/manual/en/book.xmlreader.php), [`xmlwriter`](https://www.php.net/manual/en/book.xmlwriter.php)
73+
- `kitchen-sink`: Default choice. Installs [`gd`](https://www.php.net/manual/en/book.image.php), [`mbstring`](https://www.php.net/manual/en/mbstring.installation.php), [`iconv`](https://www.php.net/manual/en/function.iconv.php), [`openssl`](https://www.php.net/manual/en/book.openssl.php), [`libxml`](https://www.php.net/manual/en/book.libxml.php), [`xml`](https://www.php.net/manual/en/xml.installation.php), [`dom`](https://www.php.net/manual/en/intro.dom.php), [`simplexml`](https://www.php.net/manual/en/book.simplexml.php), [`xmlreader`](https://www.php.net/manual/en/book.xmlreader.php), and [`xmlwriter`](https://www.php.net/manual/en/book.xmlwriter.php)
74+
- `light`: It saves 6MB of downloads and loads none of the extensions above.
75+
76+
```js
77+
{
78+
"phpExtensionBundles": [
79+
"kitchen-sink"
80+
],
81+
}
82+
```
6283

6384
## Features
6485

65-
The `features` property is used to enable or disable certain features of the Playground. It can contain the following properties:
86+
You can use the `features` property to turn on or off certain features of the Playground instance. It can contain the following properties:
6687

67-
- `networking`: Defaults to `false`. Enables or disables the networking support for Playground. If enabled, [`wp_safe_remote_get`](https://developer.wordpress.org/reference/functions/wp_safe_remote_get/) and similar WordPress functions will actually use `fetch()` to make HTTP requests. If disabled, they will immediately fail instead.
88+
- `networking`: Defaults to `false`. Enables or disables the networking support for Playground. If enabled, [`wp_safe_remote_get`](https://developer.wordpress.org/reference/functions/wp_safe_remote_get/) and similar WordPress functions will actually use `fetch()` to make HTTP requests. If disabled, they will immediately fail instead. You will need this property enabled if you want the user to be able to install plugins or themes.
89+
90+
```js
91+
{
92+
"features": {
93+
"networking": true
94+
},
95+
}
96+
```
97+
98+
## Steps
99+
100+
Arguably the most powerful property, `steps` allows you to configure the Playground instance with preinstalled themes, plugins, demo content, and more. The following example logs the user in with a dedicated username and password. It then installs and activates the Gutenberg plugin. [Learn more about steps](./05-steps.md).
101+
102+
```js
103+
{
104+
"steps": [
105+
{
106+
"step": "login",
107+
"username": "admin",
108+
"password": "password"
109+
},
110+
{
111+
"step": "installPlugin",
112+
"pluginZipFile": {
113+
"resource": "wordpress.org/plugins",
114+
"slug": "gutenberg"
115+
}
116+
},
117+
]
118+
}
119+
```
Lines changed: 229 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,229 @@
1+
const shouldRebuild =
2+
new URLSearchParams(window.location.search).get('rebuild') === 'true';
3+
4+
let __moduleGithubToken = localStorage.getItem('GITHUB_TOKEN');
5+
const repos = [
6+
'wordpress/wordpress-playground',
7+
'wordpress/playground-tools',
8+
'wordpress/blueprints',
9+
'wordpress/blueprints-library',
10+
'adamziel/playground-docs-workflow',
11+
'adamziel/site-transfer-protocol',
12+
];
13+
14+
const comparableKey = (str) => str.toLowerCase();
15+
16+
const graphqlQuery = async (query, variables) => {
17+
const headers = {
18+
'Content-Type': 'application/json',
19+
};
20+
if (__moduleGithubToken) {
21+
headers['Authorization'] = `Bearer ${__moduleGithubToken}`;
22+
}
23+
const response = await fetch('https://api.github.com/graphql', {
24+
method: 'POST',
25+
headers,
26+
body: JSON.stringify({ query, variables }),
27+
});
28+
return response.json();
29+
};
30+
31+
async function* iterateIssuesPRs(repo, labels = []) {
32+
const query = `
33+
query GetProjects($cursor: String!, $query: String!) {
34+
search(query: $query, first: 100, type: ISSUE, after: $cursor) {
35+
pageInfo {
36+
hasNextPage
37+
endCursor
38+
}
39+
edges {
40+
node {
41+
... on Issue {
42+
number
43+
title
44+
url
45+
body
46+
state
47+
repository {
48+
nameWithOwner
49+
}
50+
labels(first: 10) {
51+
nodes {
52+
name
53+
}
54+
}
55+
}
56+
... on PullRequest {
57+
number
58+
title
59+
url
60+
body
61+
state
62+
repository {
63+
nameWithOwner
64+
}
65+
labels(first: 10) {
66+
nodes {
67+
name
68+
}
69+
}
70+
}
71+
}
72+
}
73+
}
74+
}
75+
`;
76+
77+
let cursor = '';
78+
do {
79+
const labelQuery = labels.map((label) => `"${label}"`).join(',');
80+
const variables = {
81+
cursor,
82+
query:
83+
`repo:${repo}` + (labels.length ? ` label:${labelQuery}` : ''),
84+
};
85+
86+
const response = await graphqlQuery(query, variables);
87+
const edges = response.data.search.edges;
88+
for (const edge of edges) {
89+
if (edge.node) {
90+
const item = edge.node;
91+
const key = comparableKey(
92+
`${item.repository.nameWithOwner}#${item.number}`
93+
);
94+
item.key = key;
95+
item.title = item.title.trim().replace(/^Tracking: /, '');
96+
yield edge.node;
97+
}
98+
}
99+
if (!response.data.search.pageInfo.hasNextPage) {
100+
break;
101+
}
102+
cursor = response.data.search.pageInfo.endCursor;
103+
} while (true);
104+
}
105+
106+
const nodesCacheKey = 'nodes_cache';
107+
108+
const fetchData = async () => {
109+
let allNodes = {};
110+
const allNodesArray = [];
111+
for (const repo of repos) {
112+
for await (const item of iterateIssuesPRs(repo)) {
113+
allNodes[item.key] = item;
114+
}
115+
for await (const item of iterateIssuesPRs(repo, [
116+
'[Type] Mindmap Node',
117+
'[Type] Mindmap Tree',
118+
])) {
119+
allNodes[item.key] = item;
120+
}
121+
}
122+
return allNodes;
123+
};
124+
125+
const getConnectedNodes = (issue) => {
126+
const currentRepo = issue.repository.nameWithOwner;
127+
let connections = [];
128+
129+
const regex1 =
130+
/\bhttps:\/\/github.com\/([^\/]+)\/([^\/]+)\/(?:issues|pull)\/(\d+)\b/g;
131+
const regex2 = /\b#(\d+)\b/g;
132+
let match;
133+
134+
while ((match = regex1.exec(issue.body)) !== null) {
135+
connections.push(`${match[1]}/${match[2]}#${match[3]}`);
136+
}
137+
138+
while ((match = regex2.exec(issue.body)) !== null) {
139+
connections.push(`${currentRepo}#${match[1]}`);
140+
}
141+
142+
return connections.map(comparableKey);
143+
};
144+
145+
const buildEdges = ({ allNodes, rootKey, isEdge }) => {
146+
const seen = {};
147+
const allEdges = {};
148+
149+
const preorderTraversal = (currentNode) => {
150+
const relatedIssueKeys = getConnectedNodes(currentNode).filter(
151+
(edgeKey) => isEdge(currentNode.key, edgeKey)
152+
);
153+
154+
for (const relatedKey of relatedIssueKeys) {
155+
if (!allNodes[relatedKey]) continue;
156+
if (seen[relatedKey]) continue;
157+
seen[relatedKey] = true;
158+
159+
if (!allEdges[currentNode.key]) {
160+
allEdges[currentNode.key] = [];
161+
}
162+
163+
allEdges[currentNode.key].push(relatedKey);
164+
preorderTraversal(allNodes[relatedKey]);
165+
}
166+
};
167+
168+
preorderTraversal(allNodes[rootKey]);
169+
return allEdges;
170+
};
171+
172+
const buildTree = (allNodes, allEdges, rootKey) => {
173+
const node = { ...allNodes[rootKey] };
174+
const childrenKeys = allEdges[rootKey] || [];
175+
node.children = childrenKeys.map((childKey) =>
176+
buildTree(allNodes, allEdges, childKey)
177+
);
178+
return node;
179+
};
180+
181+
export const fetchMindmapData = async ({ githubToken } = {}) => {
182+
if (githubToken) {
183+
__moduleGithubToken = githubToken;
184+
}
185+
186+
const allNodes = await fetchData();
187+
const isEdge = (fromKey, toKey) => {
188+
if (mindmapTrees[fromKey]) {
189+
return true;
190+
}
191+
if (mindmapNodes[fromKey] && mindmapNodes[toKey]) {
192+
return true;
193+
}
194+
return false;
195+
};
196+
197+
const mindmapTrees = {};
198+
const mindmapNodes = {};
199+
for (const key in allNodes) {
200+
if (
201+
allNodes[key].labels.nodes.some(
202+
(label) => label.name === '[Type] Mindmap Tree'
203+
)
204+
) {
205+
mindmapTrees[key] = allNodes[key];
206+
mindmapNodes[key] = allNodes[key];
207+
} else if (
208+
allNodes[key].labels.nodes.some(
209+
(label) => label.name === '[Type] Mindmap Node'
210+
)
211+
) {
212+
mindmapNodes[key] = allNodes[key];
213+
}
214+
}
215+
216+
const rootKey = 'wordpress/wordpress-playground#525';
217+
const allEdges = buildEdges({
218+
allNodes,
219+
rootKey,
220+
isEdge,
221+
});
222+
const tree = buildTree(allNodes, allEdges, rootKey);
223+
console.log({
224+
allNodes,
225+
tree,
226+
});
227+
228+
return tree;
229+
};
Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,13 @@
1+
<!DOCTYPE html>
2+
<html lang="en">
3+
<head>
4+
<meta charset="UTF-8" />
5+
<title>Mind Map</title>
6+
<link rel="stylesheet" href="style.css" />
7+
</head>
8+
<body>
9+
<div id="mindmap"></div>
10+
<script src="https://d3js.org/d3.v6.min.js"></script>
11+
<script src="script.js"></script>
12+
</body>
13+
</html>

0 commit comments

Comments
 (0)