ðŸ Gato GraphQLãã¹ã³ãŒãåãããŸãããPHP-Scoperã®ãããã§ãïŒ
ãã©ã°ã€ã³ Gato GraphQL ãã¹ã³ãŒãåãããŸãããããã«ããããã©ã°ã€ã³ãã€ãã« WordPress ãã©ã°ã€ã³ãã£ã¬ã¯ããªã«ã¢ããããŒãã§ããããã«ãªããŸããã

ãããå®çŸããããã«ãçŽ æŽããã PHP-Scoper ã䜿çšããŠããŸãããã®ã©ã€ãã©ãªã WordPress ã§äœ¿çšããã®ã¯äžççžã§ã¯ãããŸããã®ã§ãã©ã®ããã«ä¹ãè¶ãããããã®ããã°èšäºã§èª¬æããŸãã
ã»ã¯ã·ã§ã³:
- ã¹ã³ãŒãåãæ±ºæãããŸã§
- ãªãã·ã§ã³ã®æ€èš
- Mozartã詊ããŠã倱æãã
- PHP-Scoperã確èªããŠããããã¯ã«ãªã
- PHP-Scoperã«æ»ããä»åºŠã¯æ¬æ°ã§
- PHP-Scoperãç°¡åãªæ¹æ³ ð ððœ ããããç§ã®è§£æ±ºçãå§ãŸããŸã
- å®éã®ã³ãŒããèŠããŠãã ãã
- ãã¹ã
- çµæã確èªãã
ã¹ã³ãŒãåãæ±ºæãããŸã§
æ°é±éåãMatt Mullenweg ããGraphQL ãã©ã°ã€ã³ããæ³šèŠãããšçºè¡šããŸãããæããã« WPGraphQL ãæããŠããŸãã圌ã®çºèšã¯ãGraphQL ãã©ã°ã€ã³ãäžã€ãããªããšèããŠããããšã瀺ããŠããŸãããå®éã«ã¯äºã€ãããŸãïŒé€å€ãããã®ã¯ããŸããç§ã®ãã®ã§ãïŒãããã«ãããç§ã®ãã©ã°ã€ã³ãããã«æ³šç®ãããŠããªãããæãç¥ããæãããæããŸããã
Matt ã¯ç§ã®ãã©ã°ã€ã³ãååšããããšãç¥ããŸããã§ãããWordPress ã³ãã¥ããã£ã®å€§éšåãåæ§ã§ããæããã«å®£äŒãè¶³ããŠããŸãããããŒã±ãã£ã³ã°ããœãŒã·ã£ã«ã¡ãã£ã¢ã¯åŸæã§ã¯ãããŸãããæè¡çãªããšã¯ããããã§ãããšæã£ãŠããŸãããããã§ãå°ãªããšãèªåã®èœåã®ç¯å²å ã§äœãè¡åããããšã«ããŸããã
çŸåšåãçµãã§ããããšã¯æ¬¡ã®ãšããã§ãã
- ãã®ãŠã§ããµã€ã gatographql.com ã®ã³ãŒãã£ã³ã°ãçµããŠã2 é±éåã«ãªãªãŒã¹ããŸããïŒãã£ãïŒð¥³ ãšããã§ãã©ãæããŸããïŒDM ã ã¡ãŒã« ã§ãã£ãŒãããã¯ãããã ããã°å¬ããã§ãïŒ
- 3 æ¥åã«ãã©ã°ã€ã³ã®ã¹ã³ãŒãåãéå§ããæšæ¥ãã®äœæ¥ãçµããŸããïŒïŒåå 3 æã§ããããããããããããŸãã ð ïŒ
- ãããŠæåŸã«ã次ã®ããŒãžã§ã³
0.8ã®äœæ¥ããã§ã«é²ããŠãããããããã©ã°ã€ã³ãªããžããªã§å©çšå¯èœã«ãªãæåã®ããŒãžã§ã³ã«ãªããŸã
ãã©ã°ã€ã³ãã¹ã³ãŒãåããããšã¯ãªããžããªãžã®ã¢ããããŒãã«å¿ é ã§ããããããªããã°ãç§ã®ãã©ã°ã€ã³ãšåãäŸåé¢ä¿ãå¿ èŠãšããå¥ã®ãã©ã°ã€ã³ãšãããŒãžã§ã³ãç°ãªãå Žåã«ç«¶åãçºçããå¯èœæ§ãããããã§ãããããéæããããšã¯æ¬åœã«å€§ããªãã€ã«ã¹ããŒã³ã§ããããããéèŠãªéçºã¯ãããŸãããããšãã°ãWordPress ã®ããŒã¿ã¢ãã«ãšå®å šã«äžèŽãããã GraphQL ã¹ããŒãã宿ãããå¿ èŠããããŸãããããã¯åæ°ãªãªãŒã¹ã§çå®ã«é²ããŠãããŸãã
æ°é±éåŸã«ã¯ããGraphQLãã§æ€çŽ¢ãããšãã«ãã©ã°ã€ã³ã衚瀺ãããããã«ãªããGraphQL API ã®å®è£ ãæ¬åœã«å¿ èŠãšããŠãã人ã ãç§ã®ãã©ã°ã€ã³ã®ååšãç¥ãããã«ãªãã§ãããã
確ãã«ãç§ã¯ãã©ã°ã€ã³ã WordPress ã®æªæ¥ã«ãããŠçå£ã«æ€èšããŠã»ãããšæã£ãŠããŸããæ°å¹Žã«ããã£ãŠåãçµãã§ããŸããããªããžããªã¯ 2016 幎 8 æã«éå§ãããŸããããã㯠WPGraphQL ãååšããåã§ãGraphQL ã®é»ææã§ãããããããã®ãããžã§ã¯ãã GraphQL ãµãŒããŒã«ãªããšã¯ç¥ããŸããã§ããããã®æ¹åæ§ã«è»¢æããã®ã¯ããã 1.5 幎åã®ããšã§ãã
ïŒãã®ãããžã§ã¯ãã¯å®éã«ã¯ãµãŒããŒãµã€ãã³ã³ããŒãã³ãã䜿çšããã¢ããªã±ãŒã·ã§ã³æ§ç¯ã®ããã®ãã¬ãŒã ã¯ãŒã¯ã§ããã®ã¢ãŒããã¯ãã£ã䜿ãã° GraphQL ãµãŒããŒãå®ç§ã«æ§ç¯ã§ããŸããã ããããã®ãŸãŸæ§ç¯ããã ãã§ããïŒ
WPGraphQL ã¯ç¢ºç«ããããã©ã°ã€ã³ã§ãããããã¯åœç¶ã®ããšã§ããæ°å¹Žåã«éå§ãããã³ãã¥ããã£ã圢æãããŸãããJason BahlïŒGatsby ã«éçšãããŠããïŒãšãããžã§ã¯ãã®è²¢ç®è ã®ä»äºã¯åè¶ããŠããŸããWordPress ã Jamstack ã«çµ±åããããšããããŸã§ã«ãªãç°¡åã«ãªããŸããã
ããããGatsby ãš Jamstack ã¯äžã€ã®ãã®ã§ãããWordPress ã¯å¥ã®ãã®ã§ããWordPress ã¯ãŠã§ãã® 40% ãå ããŠãããåãªãéçãµã€ããžã§ãã¬ãŒã¿ãŒãžã®å ¥åã§ã¯ãããŸããã
ã ããããä»ãä»£æ¿ææ®µããªãããã«ãã®æ±ºå®ãæŒãã€ããããããšãªããWPGraphQL ãé©åãªéžæè¢ãã©ãããæ€èšã§ããŸããäž¡ãã©ã°ã€ã³ãåæããŠãã©ã¡ãã®ç®æšã WordPress ã«ãšã£ãŠéèŠãªããšã«ããäžèŽããŠãããã確èªã§ããŸãã
Gato GraphQL ã Jamstack ã§åäœããŸãããããããã®äž»ãªç®æšã¯ããçŽ æŽããããšæããŸãããããŒã¿å ¬éãæ°äž»åãããããšãã€ãŸã API ã®ç·šéãæçš¿ã®ç·šéãšåããããç°¡åã«ããããšïŒèª°ã§ãã§ããããšïŒããã㊠WordPress ããŠã§ãã® OS ã«ããããšã§ãã
ãã©ã°ã€ã³ããªããžããªã§å©çšå¯èœã«ãªãã°ãããå€ãã®äººãããã詊ããŠãããã¯æ¬åœã«çŽ æŽãããïŒãªãä»ãŸã§ç¥ããªãã£ããã ïŒããšèšã£ãŠãããããšãæåŸ ããŠããŸãã
ããããã°ããGraphQL ãã©ã°ã€ã³ãã®éžæã¯äºåã«æ±ºãŸã£ãŠããããWordPress ã³ãã¥ããã£ã¯ WPGraphQL ãš Gato GraphQL ã®äž¡æ¹ãããããã®ã¡ãªããã«åºã¥ããŠæ€èšã§ããããã«ãªããŸãã
åæ©ã®èª¬æãçµãã£ãã®ã§ãæè¡çãªè©±ãããŸããã ð€ã
ãªãã·ã§ã³ã®æ€èš
ãã©ã°ã€ã³ã®ã¹ã³ãŒãåã«ã¯ããã©ã°ã€ã³ã®ã³ãŒããå ¥åãšããŠåãåããã¹ã³ãŒãåããããã©ã°ã€ã³ãåºåããããŒã«ãå®è¡ããå¿ èŠããããŸããããããããšã§ã¯ãããŸããããïŒã©ãã»ã©é£ããã®ã§ããããïŒ

ã³ãŒãããŒã¹ã«ãã£ãŠã¯ãã¹ã³ãŒãã³ãã³ããå®è¡ããã ãã§ã¯äžååãªå ŽåããããŸãããã®åŸãã³ã³ãœãŒã«ã®ãšã©ãŒã確èªããä¿®æ£ããã¢ããªã±ãŒã·ã§ã³ã培åºçã«ãã¹ããããšã©ãŒãšãã®åå ãç¹å®ããä¿®æ£ããŠãç¹°ãè¿ãå¿ èŠããããŸããå®å šã«æ£ããããã«ã¯ãããçšåºŠã®æéããããå ŽåããããŸãã
ã¹ã³ãŒãåã«ã¯ 2 ã€ã®ã©ã€ãã©ãªããããããããç°ãªãç®çãæã£ãŠããŸãã
- MozartãWordPress ã³ãŒãåã
- PHP-Scoperããããã PHP ã³ãŒãåããç¹ã« PHAR ãçæããå Žå
WordPress ãã©ã°ã€ã³ãæã£ãŠããã®ã§ããŸã Mozart ã詊ããŸãããã©ãã ã£ããèŠãŠã¿ãŸãããã
Mozartã詊ããŠã倱æãã
Mozart ãçŽ 1 幎åã«è©ŠããŸãããããã¥ã¡ã³ãã«ãããšãmozart compose ã³ãã³ãããã¹ãŠã®éæ³ãè¡ãããšã®ããšã§ãããªã®ã§ããã¹ãŠãéåžžã«çŽ æ©ãç°¡åã«æžã¿ãæ®ãã®æ¥ããã€ããªã楜ããã§éããããšæåŸ
ããŠããŸããã
æ®å¿µãªãããMozart ã¯ç§ã®ã³ãŒãããŒã¹ã§ã¯åäœããŸããã§ãããåé¡ãçºçãç¶ãããããã¹ã³ãŒãåã¯å®çŸããŸããã§ãããå¿ èŠãªæ¯æŽãåŸãããŸããã§ãããPR ãæåºããŸããããããŒãžã®æ€èšããããããã®ããšããéç¥ãããªãã£ããããèªç¶ãšãã®ãããžã§ã¯ããžã®èå³ã倱ããŸã§åŸ ã¡ç¶ããããšã«ãªããŸããã
Mozart ãç§ã®ãã©ã°ã€ã³ã®äŸåé¢ä¿ã®äžéšãåŠçã§ããªãã£ããšæããŸããSymfony ã®ããã€ãã®ã³ã³ããŒãã³ãã䜿çšããŠãããDependencyInjectionãCacheãDotenv ãå«ãŸããŠããããã¹ãŠ Composer ã§ç®¡çãããŠããŸãã
PHP ã®ã¹ã³ãŒãåã¯åã« PHP ã ãã®åé¡ã§ã¯ãããŸãããã¹ã³ãŒããŒã«ã¯åé¿ãã¹ãå€ãã®ããŒãã«ãšè§£æ±ºãã¹ã課é¡ããããŸããããšãã°ãSymfony DependencyInjection ã¯èšå®ã®ããã« YAML ãã¡ã€ã«ã䜿çšããŠãããããããã¹ã³ãŒãåããå¿
èŠããããŸãããŸããcomposer.json ãã¡ã€ã«ã«ã¯ PSR-4 ãªãŒãããŒãã£ã³ã°ã®èšå®ãå«ãŸããŠããããããã¹ã³ãŒãåããå¿
èŠããããŸããMozart ã¯ãããã®è€éããé©åã«åŠçã§ããªãã£ããšæããŸãã
ããããç§ã®çµéšãå¯äžã®ãã®ã§ã¯ãªããšç¢ºä¿¡ããŠãããæºè¶³ããŠãããŠãŒã¶ãŒãããããããããšã§ãããããŸããç§ã®å€±æãã詊ã¿ã¯ 1 幎åã®ããšãªã®ã§ããã®åŸããŒã«ãæ¹åãããŠãããããããŸããããããŠãå¿ããªãã§ãã ããããã¹ã³ãŒãåããããã©ã°ã€ã³ã¯ãã¹ãŠäŒŒãŠãããã¹ã³ãŒãåãããŠããªããã©ã°ã€ã³ã¯ããããç¬èªã®æ¹æ³ã§ã¹ã³ãŒãåãããŠããªãããšããèšèãããããã«ãããããããç§ã ãã®åé¡ãããããŸããã
WordPress ãã©ã°ã€ã³ãã·ã³ãã«ã§ãèªå·±å®çµããããžãã¯ãæã¡ãã¹ã³ãŒãåã PHP ã³ãŒãå ã§ã®ã¿è¡ãããå Žåã¯ãMozart ãæ©èœããå¯èœæ§ããããŸãã詊ããŠã¿ããããããŸããã
PHP-Scoperã確èªããŠããããã¯ã«ãªã
次㫠PHP-Scoper ã«åãããŸãããããããããã«æããªã£ãŠããŸãã詊ãããšããããŸããã§ããã
ãŸãããã®ããŒã«ã¯ WordPress ãèªç¶ã«ãµããŒãããŠããŸãããæ¬¡ã«ã圌ãèªèº«ã® Makefile ãèŠãããå§ããããŠãããããã¯æ¬¡ã®ããã«èŠããŸãã
# See https://tech.davis-hansson.com/p/make/
MAKEFLAGS += --warn-undefined-variables
MAKEFLAGS += --no-builtin-rules
.DEFAULT_GOAL := help
PHPBIN=php
PHPNOGC=php -d zend.enable_gc=0
IS_PHP8=$(shell php -r "echo version_compare(PHP_VERSION, '8.0.0', '>=') ? 'true' : 'false';")
SRC_FILES=$(shell find bin/ src/ -type f)
.PHONY: help
help:
@echo "\033[33mUsage:\033[0m\n make TARGET\n\n\033[32m#\n# Commands\n#---------------------------------------------------------------------------\033[0m\n"
@fgrep -h "##" $(MAKEFILE_LIST) | fgrep -v fgrep | sed -e 's/\\$$//' | sed -e 's/##//' | awk 'BEGIN {FS = ":"}; {printf "\033[33m%s:\033[0m%s\n", $$1, $$2}'
#
# Build
#---------------------------------------------------------------------------
.PHONY: clean
clean: ## Clean all created artifacts
clean:
git clean --exclude=.idea/ -ffdx
update-root-version: ## Check the lastest GitHub release and update COMPOSER_ROOT_VERSION accordingly
update-root-version:
rm .composer-root-version || true
$(MAKE) .composer-root-versionããã« 600 è¡ä»¥äžããã¹ãŠãã®ãããªå 容ã§ãããŸãã§è¬ã ã®ããã§ãããã©ã°ã€ã³ãã¹ã³ãŒãåããããã ãã«ãã®ã³ãŒããçè§£ããå¿ èŠããããšæããæ ãŠãŠéãåºããŸããã
ïŒãŸãããã®ã³ãŒããçè§£ããããšã¯ã¹ã³ãŒãåãããã¢ããªã±ãŒã·ã§ã³ããã¹ãããããã®æšå¥šäºé
ã§ãããå¿
é ã§ã¯ãããŸãããåçŽã« php-scoper add-prefix ã³ãã³ããå®è¡ããŠããã¹ãŠã®éæ³ãããããŠããã€ããªã飲ã¿ã«è¡ãããšãã§ããŸããïŒ
PHP-Scoperã«æ»ããä»åºŠã¯æ¬æ°ã§
3 æ¥åããªããšãã¹ã³ãŒãåãå®è£ ããããšæ±ºæããŸãããã©ãããŠãå®çŸãããªããã°ãªããŸããã§ããã
PHP-Scoper ã«æ»ããæ¬è °ãå ¥ããŠè©ŠããŠã¿ãããšã«ããŸãããPHP Scoper: How to Avoid Namespace Issues in your Composer DependenciesïŒDelicious Brains ã®åªç§ãªããŒã ã«ããïŒãèªãã§ãããã§ WordPress ãã¹ã³ãŒãåã§ããããšãç¥ã£ãŠããŸãããããšã¯å§¿å¢ãšç²ã匷ãã®åé¡ã§ããã
æ¢åã®ãœãªã¥ãŒã·ã§ã³ãããã€ãæ¢ã£ãŠã¿ãŸããã
- Lucas Bustamante ã«ãããã
- Yoast ã«ãããã
- Google Site Kit ã«ãããã
- Google Web Stories ã«ãããã
ããããã©ããå®å šã«æºè¶³ã§ãããã®ã§ã¯ãããŸããã§ãããã³ãŒããããã¯çã«èŠããããè匱ã§ãã€ãå£ããããªãã®ã§ããã
ããšãã°ãGoogle Web Stories ãã©ã°ã€ã³ã¯ã³ãŒããã¹ã³ãŒãåãããã®åŸåç«¶åãå ã«æ»ããŸãã
return [
'patchers' => [
function ( $file_path, $prefix, $contents ) {
/*
* There is currently no easy way to simply whitelist all global WordPress functions.
*
* This list here is a manual attempt after scanning through the AMP plugin, which means
* it needs to be maintained and kept in sync with any changes to the dependency.
*
* As long as there's no built-in solution in PHP-Scoper for this, an alternative could be
* to generate a list based on php-stubs/wordpress-stubs. devowlio/wp-react-starter/ seems
* to be doing just this successfully.
*
* @see https://github.com/humbug/php-scoper/issues/303
* @see https://github.com/php-stubs/wordpress-stubs
* @see https://github.com/devowlio/wp-react-starter/
*/
$contents = str_replace( "\\$prefix\\_doing_it_wrong", '\\_doing_it_wrong', $contents );
$contents = str_replace( "\\$prefix\\__", '\\__', $contents );
$contents = str_replace( "\\$prefix\\esc_html_e", '\\esc_html_e', $contents );
$contents = str_replace( "\\$prefix\\esc_html", '\\esc_html', $contents );
$contents = str_replace( "\\$prefix\\esc_attr", '\\esc_attr', $contents );
$contents = str_replace( "\\$prefix\\esc_url", '\\esc_url', $contents );
$contents = str_replace( "\\$prefix\\do_action", '\\do_action', $contents );
// ...
}
]
]ãªãããããã®ãçè§£ã§ããŸããã奜ãã§ã¯ãããŸãããæ°ãã WordPress 颿°ãåç §ããããã³ã«ããã®ãªã¹ãã«ã远å ããããšã確èªããå¿ èŠããããŸããæåãããŠãè匱ãããŸãã
ãããç§ã®èª²é¡ã§ããããã©ã°ã€ã³ãã¹ã³ãŒãåããããç°¡åãªæ¹æ³ããããå人ãååã«èŠããŠãæ¥ãããããªãã³ãŒãã«äŸåã§ããªãã§ããããïŒ
PHP-Scoperãç°¡åãªæ¹æ³ ð
æã£ãŠããããç°¡åã§ããïŒãããæ°æéã§ããã¹ãŠãåäœããããã«ãªããŸããã

ãç°¡åããšãæ°æéããšèšããšããå®éã«ã¯æ¬¡ã®ããšãæå³ããŸããã³ãŒãããŒã¹ã«é©åãªæ§é ãäœæããããã« 2 ã¶æãè²»ãããåŸã«åããŠãã¹ãŠãããã«åäœããããšããããšã§ãïŒåŸã§è©³ãã説æããŸãïŒã
ãããéèŠãªããšã¯ããããžã§ã¯ãã®é©åãªã»ããã¢ãããããã°ãã¹ã³ãŒãåã¯ããã«éæã§ãããšããããšã§ãã
WordPress ã³ãŒããã¹ã³ãŒãåããéã®åé¡ã¯ããŸãã« WordPress ã³ãŒããã®ãã®ã§ããåé¡ã¯ãã¡ãã§èª¬æãããŠããŸãããèŠããã«ãã¹ãŠã® WordPress 颿°ãšã¯ã©ã¹ãããŒã ã¹ããŒã¹åãããŠããŸããšããããšã§ããã³ãŒãã§ WP_Query ãåç
§ããã get_posts ãåŒã³åºããããããšãããã㯠MyPrefixedNamespace\WP_Query ãš MyPrefixedNamespace\get_posts ã«å€æãããå®è¡æã«å€§å€±æãæããŸãããããŠãã㯠PHP-Scoper ã§ã¯ããã¯ãªãã«åé¿ã§ããŸããã
ã§ã¯ãããã®è§£æ±ºçã¯äœã§ããããïŒç°¡åã§ããã¹ã³ãŒãåãããã³ãŒãããŒã¹ã§ WP_Query ãåç
§ããããget_posts ãåŒã³åºããããWordPress ã®ã³ãŒãã䜿çšãããããªãããšã§ãã

ããããç§ã¯çã£ãŠããŸããããããªããåãã ãšæããŸãããããŠã確ãã« WordPress ãã©ã°ã€ã³ãæ§ç¯ããŠããŸãâŠèª¬æãããŠãã ããã
ã©ã®ããã«ã㊠WordPress ã³ãŒããå«ããªãããã«ããã®ã§ããããïŒã³ãŒãããŒã¹ã 2 ã»ããã®ããã±ãŒãžã«åå²ããããšã§å®çŸããŸãã
- WordPress ã³ãŒããå«ã¿ãå€éšã©ã€ãã©ãªã®ã³ãŒããåç §ããªããã®
- ããžãã¹ããžãã¯ãå«ã¿ãWordPress ã³ãŒããäžåå«ãŸããå¿ èŠãªäŸåé¢ä¿ãšãã®ã³ãŒããžã®åç §ããã¹ãŠå«ããã®
ãã®ããã«ããŠãåäžã®ã³ãŒãããŒã¹ãæã€ä»£ããã«ãè€æ°ã®ã³ãŒãããŒã¹ïŒãŸãã¯ããã±ãŒãžïŒãæã¡ãŸããäžéšã¯ã¹ã³ãŒãåãããäžéšã¯ã¹ã³ãŒãåãããããã¹ãŠã Composer ãéããŠçµã³ã€ããŠãã©ã°ã€ã³ã圢æããŸãã
ãããŠãWordPress ã³ãŒããå«ãããã±ãŒãžã¯ã¹ã³ãŒãåãããç«¶åãåé¿ããŸãããããæ©èœããã®ã¯ãå€éšäŸåé¢ä¿ã«å±ããã³ãŒããåç
§ããŠããªãããã§ãããã¹ãŠã®åç
§ã¯ MyNamespace\MyPlugin\MyClass ã®ãããªå
éšåç
§ã§ãããããããããã¯ã¹ã³ãŒãåããå¿
èŠã¯ãããŸãããWordPress ãµã€ãã«ã€ã³ã¹ããŒã«ããããã©ã°ã€ã³ã®ããŒãžã§ã³ã¯ 1 ã€ã ããšå®å
šã«ä»®å®ã§ããèªåã®ããŒã ã¹ããŒã¹ MyNamespace\* ããã¯ã€ããªã¹ãã«ç»é²ã§ããããã§ãã
ããã«ããã©ã°ã€ã³ãæ¡åŒµå¯èœãªå Žåãèªåã®ããŒã ã¹ããŒã¹ããã¯ã€ããªã¹ãã«ç»é²ããããšã¯å¿
é ã§ããããšãã°ãGato GraphQL ã®ãã£ãŒã«ããªãŸã«ãã¯ã¯ã©ã¹ PoP\ComponentModel\FieldResolvers\AbstractFieldResolver ãæ¡åŒµããŠå®è£
ãããŸããã¹ã³ãŒãåããå Žåãéçºè
ã¯éçºæã« PoP\ComponentModel\FieldResolvers\AbstractFieldResolver ãåç
§ããæ¬çªç°å¢ã§ã¯ PrefixedByPoP\PoP\ComponentModel\FieldResolvers\AbstractFieldResolver ãåç
§ããããšã匷ããããŸããããã¯åãå
¥ããããŸããã
ãããã£ãŠãå€éšã©ã€ãã©ãªãžã®ãã¹ãŠã®åç §ãå«ãã WordPress ã³ãŒãã¯å«ãŸãªãããžãã¹ããžãã¯ããã±ãŒãžã®ã¿ãã¹ã³ãŒãåããŸãã
èŠçŽãããšããã®æŠç¥ãåãæ¿ããŸãã
ãåäžã®ã³ãŒãããŒã¹ãæã¡ãã¹ã³ãŒãåãããã®åŸå€å€§ãªèŠåŽãšå¿èããã£ãŠãã¡ãŒãžãå ã«æ»ããç«¶åãèŠéãããŠæ¬çªç°å¢ã§ ð£ ççºããªãããšãç¥ãã
ããã«å€ããŸãã
ãã³ãŒãããŒã¹ã 2 ã€ã®ã°ã«ãŒãã«åå²ããå€éšäŸåé¢ä¿ãžã®åç §ãå«ã¿ WordPress ã³ãŒããå«ãŸãªãæ¹ã®ã¿ãã¹ã³ãŒãåããŠããã皌ãã ãã€ããªã飲ã¿ã«è¡ã ð¹ã
å®éã®ã³ãŒããèŠããŠãã ãã
ãœãŒã»ãŒãžãéããŠãæ¬ç©ã®èãå ¥ã£ãŠããã確ãããæãæ¥ãŸãã ðã
4 æ¥åãç§ã®ãã©ã°ã€ã³ã«ã¯æ¬¡ã®ã³ãŒãããããŸããã
namespace GraphQLAPI\GraphQLAPI\ContentProcessors;
use Parsedown;
class MarkdownContentParser
{
protected function getHTMLContent(string $fileContent): string
{
return (new Parsedown())->text($markdownContent);
}
}ã¯ã©ã¹ Parsedown ã¯ããã©ã°ã€ã³ã® composer.jsonã§å®çŸ©ãããŠããå€éšäŸåé¢ä¿ erusev/parsedown ããæ¥ãŠããŸãã
{
"require": {
"erusev/parsedown": "^1.7"
}
}ãããã£ãŠãç§ã®ãã©ã°ã€ã³ã«ã¯å€éšã©ã€ãã©ãªãžã®åç
§ãå«ãŸããŠãããããã¹ã³ãŒãåã㊠Parsedown ã PrefixedByPoP\Parsedown ã«å€æããå¿
èŠããããŸããããããããããããšãã©ã°ã€ã³å
ã®ãã¹ãŠã® WordPress ã³ãŒããã¹ã³ãŒãåãããç«¶åãçºçããŸãã
ãã®ãããã³ãŒãã graphql-api/markdown-convertor ãšããå¥ã®ããã±ãŒãžã«æœåºããcomposer.json ã®ãµãŒãããŒãã£ã®äŸåé¢ä¿ãèªåã®äŸåé¢ä¿ã«çœ®ãæããŸããã
{
"require": {
"graphql-api/markdown-convertor": "^0.8"
}
}ããã§ããã©ã°ã€ã³ã¯å€éšã©ã€ãã©ãªãçŽæ¥åç
§ããã代ããã«æ°ããããã±ãŒãžã®ãµãŒãã¹ MarkdownConvertorInterface ãåç
§ããŸãã
namespace GraphQLAPI\GraphQLAPI\ContentProcessors;
use GraphQLAPI\MarkdownConvertor\MarkdownConvertorInterface;
class MarkdownContentParser extends AbstractContentParser
{
protected MarkdownConvertorInterface $markdownConvertorInterface;
function __construct(MarkdownConvertorInterface $markdownConvertorInterface)
{
$this->markdownConvertorInterface = $markdownConvertorInterface;
}
protected function getHTMLContent(string $fileContent): string
{
return $this->markdownConvertorInterface->convertMarkdownToHTML($fileContent);
}
}ãµãŒãããŒãã£ã®äŸåé¢ä¿ãžã®åç §ã¯æ°ããããã±ãŒãžã§è¡ãããŸãã
namespace GraphQLAPI\MarkdownConvertor;
use Parsedown;
class MarkdownConvertor implements MarkdownConvertorInterface
{
public function convertMarkdownToHTML(string $markdownContent): string
{
return (new Parsedown())->text($markdownContent);
}
}æçµçã«ã以äžãè¡ãå¿ èŠããããŸãã
- äŸåé¢ä¿
graphql-api/markdown-convertorãã¹ã³ãŒãåãã - ãã©ã°ã€ã³ã³ãŒãã®ã¹ã³ãŒãåãã¹ããããã
- èªåã®ã¯ã©ã¹ãã¹ã³ãŒãåãããªããããããŒã ã¹ããŒã¹
GraphQLAPI\*ããã¯ã€ããªã¹ãã«ç»é²ãã
ãããåºæ¬çãªæŠç¥ã§ããããããã¯ããã¹ãŠã®å€éšäŸåé¢ä¿ãã³ãŒãããåãé€ãããã©ã°ã€ã³ãã¹ã³ãŒãåã§ããããã«ãªããŸã§ããã®åãã¢ã€ãã¢ãç¹°ãè¿ãããšã«ãªããŸãã
æœåºããäŸåé¢ä¿ã¯ composer.json ãã¡ã€ã«ã® require ã»ã¯ã·ã§ã³ã«ãããã®ã ãã§ããrequire-dev ã«ã€ããŠã¯ãå€éšãã©ããã«ãããããäŸåé¢ä¿ãä¿æã§ããŸããéçºã«äœ¿çšããäŸåé¢ä¿ã¯ã¹ã³ãŒãåããå¿
èŠããªããæ¬çªç°å¢ã§ãã©ã°ã€ã³ãäœæããŠãªãªãŒã¹ããããã®ãã®ã ããã¹ã³ãŒãåããå¿
èŠããããŸãã
æçµçã«ããã©ã°ã€ã³ã® composer.json ã«ã¯å€éšäŸåé¢ä¿ãå«ãŸããŠããªãã¯ãã§ããç§ã®ãã©ã°ã€ã³ã®å Žåãæ¬¡ã®ããã«ãªã£ãŠããŸãã
{
"require": {
"php": "^7.4|^8.0",
"getpop/engine-wp": "^0.8",
"graphql-api/markdown-convertor": "^0.8",
"graphql-by-pop/graphql-clients-for-wp": "^0.8",
"graphql-by-pop/graphql-endpoint-for-wp": "^0.8",
"graphql-by-pop/graphql-server": "^0.8",
"pop-schema/basic-directives": "^0.8",
"pop-schema/comment-mutations-wp": "^0.8",
"pop-schema/commentmeta-wp": "^0.8",
"pop-schema/comments-wp": "^0.8",
"pop-schema/custompost-mutations-wp": "^0.8",
"pop-schema/custompostmedia-mutations-wp": "^0.8",
"pop-schema/custompostmedia-wp": "^0.8",
"pop-schema/custompostmeta-wp": "^0.8",
"pop-schema/generic-customposts": "^0.8",
"pop-schema/media-wp": "^0.8",
"pop-schema/pages-wp": "^0.8",
"pop-schema/post-mutations": "^0.8",
"pop-schema/post-tags-wp": "^0.8",
"pop-schema/posts-wp": "^0.8",
"pop-schema/taxonomymeta-wp": "^0.8",
"pop-schema/taxonomyquery-wp": "^0.8",
"pop-schema/user-roles-access-control": "^0.8",
"pop-schema/user-roles-wp": "^0.8",
"pop-schema/user-state-mutations-wp": "^0.8",
"pop-schema/user-state-wp": "^0.8",
"pop-schema/usermeta-wp": "^0.8",
"pop-schema/users-wp": "^0.8"
}
}ãããã®ããã±ãŒãžã¯ãã¹ãŠãããŒã ã¹ããŒã¹ getpopãgraphql-apiãgraphql-by-popãpop-schema ãæã€ç§èªèº«ã®ãã®ã§ãããã©ã°ã€ã³ã®ãã¹ãŠã®ã³ãŒããå«ãäŸåé¢ä¿ã§ããã³ãŒããããé©åã«ç®¡çããããã«ç°ãªãããŒã ã¹ããŒã¹ã«åæ£ãããŠããŸãããããããå¿
èŠã¯ãããŸãããåäžã®ããŒã ã¹ããŒã¹ã䜿çšããŠãåé¡ãªãæ©èœããŸãã
ã¢ããªã±ãŒã·ã§ã³å
ã®ããã±ãŒãžæ°ãå¢ããŠãããšããã¹ãŠãã¢ããªãã«ãã¹ãããå¿
èŠããããŸããããããªããšãè€æ°ã®ããã±ãŒãžãå«ããã«ãªã¯ãšã¹ããäœæããéã«é ããããããªããŸãïŒä¿¡ããŠãã ãããçµéšããããŸãïŒãç§ã®å Žåããã¹ãŠã®ããã±ãŒãžã¯ GatoGraphQL/GatoGraphQL ã¢ããªãã«ãã¹ããããŠãããçŽ æŽããã Monorepo Builder ã䜿ã£ãŠåæãä¿ã£ãŠããŸãïŒãã®ããŒã«ã«ã€ããŠã®èšäºãæžããªããã°ãªããŸãããæ¬åœã«åœã®æ©äººã§ãïŒïŒã
ãããã®ããã±ãŒãžã®ããŒã ã¹ããŒã¹ã¯ PoPãGraphQLAPIãGraphQLByPoPãPoPSchema ã§ããç§èªèº«ã®ãã®ãªã®ã§ãã¢ããªã±ãŒã·ã§ã³ã« 1 åããçŸããªãããšãããã£ãŠãããã¹ã³ãŒãåãé¿ããããšãã§ããŸãã
ãã®ããã«ãscoper.inc.php ã§ãã¯ã€ããªã¹ãã«ç»é²ããŸãã
return [
'whitelist' => [
// Own namespaces
'PoPSchema\*',
'PoP\*',
'GraphQLByPoP\*',
'GraphQLAPI\*',
// Own container cache
'PoPContainer\*',
],
];æåŸã®ãšã³ããªã¯äŸåæ§æ³šå
¥ã³ã³ããã«å¯Ÿå¿ããŠããããããã¹ã³ãŒãåããå¿
èŠããããŸããããã©ã«ãã§ã¯ããã®ã³ã³ããã¯ã°ããŒãã«ããŒã ã¹ããŒã¹ã«çŽæ¥ ProjectServiceContainer ãšããååã§å²ãåœãŠãããŸããããã PHP-Scoper ã¯ã°ããŒãã«ããŒã ã¹ããŒã¹ã®ç¹å®ã®ã¯ã©ã¹ã®ãã¯ã€ããªã¹ãç»é²ããµããŒãããŠããŸããããã®ããã人工çãªããŒã ã¹ããŒã¹ PoPContainer ããã¯ã€ããªã¹ãã«è¿œå ããã³ã³ããããã£ã¹ã¯ã«ãã³ãããéã«ãã®ããŒã ã¹ããŒã¹ãå²ãåœãŠãŸããã
$dumper = new PhpDumper($containerBuilder);
file_put_contents(
self::$cacheFile,
$dumper->dump(
// Save under own namespace to avoid conflicts
array('namespace' => 'PoPContainer')
)
);ããã±ãŒãžã«ã€ããŠãäžéšã¯ -wp ã§çµãããã®ïŒpop-schema/users-wp ãªã©ïŒããããããã§ãªããã®ïŒgraphql-by-pop/graphql-server ãªã©ïŒãããããšã«æ°ã¥ããããããŸãããã¯ãããã®éãã§ããåè
㯠WordPress ã³ãŒããå«ã¿å€éšã©ã€ãã©ãªãžã®åç
§ããªããåŸè
ã¯å€éšã©ã€ãã©ãªãžã®åç
§ãå«ãå ŽåããããŸãããWordPress ã³ãŒãã¯äžåå«ã¿ãŸããã
ãããŠãWordPress ããã±ãŒãžã®ã¹ã³ãŒãåãã¹ãããããŸãã
return [
'finders' => [
// Scope packages under vendor/, excluding local WordPress packages
Finder::create()
->files()
->notPath([
// Exclude libraries ending in "-wp"
'#getpop/[a-zA-Z0-9_-]*-wp/#',
'#pop-schema/[a-zA-Z0-9_-]*-wp/#',
'#graphql-by-pop/[a-zA-Z0-9_-]*-wp/#',
])
->in('vendor')
]
];WordPress ããã±ãŒãžãå€éšã©ã€ãã©ãªãåç
§ããå¿
èŠããããå¥ã®ããã±ãŒãžã«æœåºã§ããªãå Žåã¯ã©ããªãã§ããããïŒããšãã°ãç§ã®ããã±ãŒãž getpop/routing-wp 㯠brain/cortex ã«äŸåããŠãããããã¯é¿ããããŸããã
getpop/routing-wp 㯠WordPress ã³ãŒããå«ãã§ãããããããã±ãŒãžå
šäœãã¹ã³ãŒãåããããšã¯ã§ããŸããã代ããã«ããããã®åç
§ãè¡ãããŠãããã¡ã€ã«ãç¹å®ãããããã®ãã¡ã€ã«ã« WordPress ã³ãŒããå«ãŸããŠããªãããšã確èªããŸããããããã°ããããã®ãã¡ã€ã«ã ããã¹ã³ãŒãåã§ããŸãã
ãã®å ŽåãCortex/Brain ãžã®åç
§ã¯ 2 ã€ã®ãã¡ã€ã«ã§è¡ãããŠãããlayers/Engine/packages/routing-wp/src/Hooks/SetupCortexHookSet.php ãå«ãŸããŠããŸãã
namespace PoP\RoutingWP\Hooks;
use PoP\Hooks\AbstractHookSet;
use Brain\Cortex\Route\RouteCollectionInterface;
use Brain\Cortex\Route\RouteInterface;
use Brain\Cortex\Route\QueryRoute;
use PoP\RoutingWP\WPQueries;
use PoP\Routing\Facades\RoutingManagerFacade;
class SetupCortexHookSet extends AbstractHookSet
{
protected function init()
{
$this->hooksAPI->addAction(
'cortex.routes',
[$this, 'setupCortex'],
1
);
}
/**
* @param RouteCollectionInterface<RouteInterface> $routes
*/
public function setupCortex(RouteCollectionInterface $routes): void
{
$routingManager = RoutingManagerFacade::getInstance();
foreach ($routingManager->getRoutes() as $route) {
$routes->addRoute(new QueryRoute(
$route,
function (array $matches) {
return WPQueries::STANDARD_NATURE;
}
));
}
}
}ããã§å¥åŠãªç¹ã«æ°ã¥ããŸãããïŒããã¯ããã¯ã®å®è£
ã§ãããadd_action ã¯åŒã³åºãããŠããŸãããããã« WordPress ã³ãŒããæãŠãªãããã§ãã代ããã«ããµãŒãã¹ HooksAPIInterface ã®é¢æ° addAction ãåŒã³åºããŠããããã®ãµãŒãã¹ã¯ããã±ãŒãž getpop/hooks-wp ã®ã¯ã©ã¹ HooksAPIã«ãã£ãŠå®è£
ãããŠãããããã§ã¯ WordPress ã³ãŒãã䜿çšã§ããŸãã
namespace PoP\HooksWP;
use PoP\Hooks\HooksAPIInterface;
class HooksAPI implements HooksAPIInterface
{
public function addAction(string $tag, callable $function_to_add, int $priority = 10, int $accepted_args = 1): void
{
add_action($tag, $function_to_add, $priority, $accepted_args);
}
}ã³ãŒãããããã«åå²ãããã®ã§ãå€éšäŸåé¢ä¿ãåç §ããŠãã 2 ã€ã®ãã¡ã€ã«ãã¹ã³ãŒãåã§ããŸãã
return [
'finders' => [
Finder::create()->append([
'vendor/getpop/routing-wp/src/Component.php',
'vendor/getpop/routing-wp/src/Hooks/SetupCortexHookSet.php',
])
]
];å ã»ã©ãã¹ã³ãŒãåã®èšå®ã«ã¯æ°æéããã£ããã2 ã¶æéã®äœæ¥ã®åŸã ãšè¿°ã¹ãŸããããã®äŸããã®æå³ã瀺ããŠããŸããå®éã®äœæ¥ã¯ã³ãŒãããŒã¹ã 2 ã€ã®ã»ããã«ãããã«åå²ããããšã«ãããŸãã
ç§ã®å Žåãäœæ¥ã« 2 ã¶æããã£ãã®ã¯ã詳现ã®ã¬ãã«ã極端ã ã£ãããã§ãããã©ã°ã€ã³ã¯ 125 åã®ããã±ãŒãžã®æ§æã«ãªããŸããïŒããããããã¯äŸå€çãªã±ãŒã¹ã§ããã©ã°ã€ã³ã®åºç€ãšãªããµãŒããŒã CMS éäŸåã«ãããšããç®æšãããã察å¿ãã -wp ããã±ãŒãžãåå®è£
ããã ãã§ä»ã® CMS ããã¬ãŒã ã¯ãŒã¯ã®å®è£
ããµããŒãããããã§ããã
ïŒãã®æŠç¥ã«ã€ããŠã¯ãAbstracting WordPress Code To Reuse With Other CMSs: Concepts ãš Implementation ã®èšäºã§è©³ããæžããŸãããïŒ
確ãã«ããªãã®äœæ¥ã§ãããã³ãŒãã®ãããããåäžããããšã§äŸ¡å€ããããŸãããããŠããã©ã°ã€ã³ã®ã¹ã³ãŒãåã ãã§ãªãïŒããã¯ç§ã«ãšã£ãŠå®å šãªé©ãã§ãäºæãã¬å¹žçŠã«ä»ã§ãã«ããŸãããŠããŸãïŒãããšãã° PHPStan ãš PHPUnit ã WordPress ãšé WordPress ã®ã³ãŒãã§å¥ã ã«å®è¡ããããšã§ãå€ãã®é çãé¿ããããšãã§ããŸãã
ã³ãŒãããŒã¹ãæŽçããããšãäžçã¯çªç¶ãã£ãšè¯ãå Žæã«ãªããŸãã
ãã¹ã
ããã§ã¯ãã©ã®ããã«ããããã¹ãããã®ã§ããããïŒ
ç§ãæãã€ãã解決çã¯ãPHP ã³ãŒããéçºçšã® PHP 7.4 ããæ¬çªçšã® 7.1 ã«ããŠã³ã°ã¬ãŒãããããã«äœ¿çšããŠããã®ãšåãããŒã« Rector ã䜿çšããããšã§ãã
ã¢ã€ãã¢ã¯æ¬¡ã®ãšããã§ãã
- ãã©ã°ã€ã³ãã¹ã³ãŒãåãã
- ä»»æã®ã«ãŒã«ãé©çšã㊠Rector ã§åæããïŒã©ã®ã«ãŒã«ã§ãæ§ããŸããïŒ
ã¹ã³ãŒãåäžã«äœããééã£ãŠããå ŽåãRector ã¯äžéšã®ã¯ã©ã¹ãããŒãã§ããããšã©ãŒãã¹ããŒããŸããããšãã°ãã¯ã©ã¹ Brain\Cortex ã PrefixedByPoP\Brain\Cortex ãšããŠã¹ã³ãŒãåãããããäžéšã®åç
§ã Brain\Cortex ã®ãŸãŸã ã£ãå Žåããã®ã¯ã©ã¹ã®ãªãŒãããŒãã倱æããŸãã
ããã¯ãã¹ãçšã® GitHub Action ã§ãïŒworking-directory ã䜿çšããŠããã®ã¯ãã¢ããªãã®ã«ãŒãããæäœããŠããŸãããã¹ã³ãŒãåã¯ãã©ã°ã€ã³ãã©ã«ãã§è¡ãããããã§ãïŒã
name: Scope Gato GraphQL tests
on:
push:
branches:
- master
pull_request: null
env:
COMPOSER_ROOT_VERSION: "dev-master"
jobs:
main:
defaults:
run:
working-directory: layers/GraphQLAPIForWP/plugins/graphql-api-for-wp
name: Scope the plugin code via PHP-Scoper, and execute tests
runs-on: ubuntu-latest
steps:
- name: Checkout code
uses: actions/checkout@v2
- name: Set-up PHP
uses: shivammathur/setup-php@v2
with:
php-version: 7.4
coverage: none
env:
COMPOSER_TOKEN: ${{ secrets.GITHUB_TOKEN }}
- name: Install root dependencies
uses: "ramsey/composer-install@v1"
- name: Install plugin dependencies for PROD
run: composer install --no-dev --no-progress --no-interaction --ansi
- name: Install PHP-Scoper
run: |
composer global config minimum-stability dev
composer global config prefer-stable true
composer global require humbug/php-scoper
# The scoped results correspond to vendor/, so must generate them in such folder
- name: Scope plugin into separate folder
run: php-scoper add-prefix --output-dir ../../../../build-prefixed/vendor --ansi
- name: Copy scoped code back into plugin
run: rsync -av build-prefixed/ layers/GraphQLAPIForWP/plugins/graphql-api-for-wp/ --quiet
working-directory: .
- name: Regenerate autoloader
run: composer dumpautoload --optimize --classmap-authoritative --ansi
- name: Run Rector on the scoped code
run: vendor/bin/rector process --config=layers/GraphQLAPIForWP/plugins/graphql-api-for-wp/rector-test-scoping.php --ansi
working-directory: .
ãããŠãããç§ã® Rector ã®èšå®ã§ãã
use Rector\CodeQuality\Rector\LogicalAnd\AndAssignsToSeparateLinesRector;
use Rector\Core\Configuration\Option;
use Symfony\Component\DependencyInjection\Loader\Configurator\ContainerConfigurator;
return static function (ContainerConfigurator $containerConfigurator): void {
$services = $containerConfigurator->services();
$services->set(AndAssignsToSeparateLinesRector::class);
$parameters->set(Option::AUTO_IMPORT_NAMES, true);
$parameters->set(Option::AUTOLOAD_PATHS, [
__DIR__ . '/vendor/scoper-autoload.php',
__DIR__ . '/vendor/erusev/parsedown/Parsedown.php',
__DIR__ . '/vendor/jrfnl/php-cast-to-type/cast-to-type.php',
__DIR__ . '/vendor/jrfnl/php-cast-to-type/class.cast-to-type.php',
]);
// files to rector
$parameters->set(Option::PATHS, [
__DIR__ . '/vendor',
]);
// files to skip
$parameters->set(Option::SKIP, [
// Exclude tests
'*/tests/*',
__DIR__ . '/vendor/nikic/fast-route/test/*',
__DIR__ . '/vendor/psr/log/Psr/Log/Test/*',
__DIR__ . '/vendor/symfony/service-contracts/Test/*',
]);
};erusev/parsedown/Parsedown.php' ãªã©ã®äžéšã®äŸåé¢ä¿ãã¡ã€ã«ã¯ Option::AUTOLOAD_PATHS ã«è¿œå ããå¿
èŠãããããšã«æ°ã¥ããããããŸãããããã¯ãããã±ãŒãžã® composer.json ã®ã¹ã³ãŒãåã 100% ä¿¡é Œã§ããããã§ã¯ãªãããªãŒãããŒãã倱æããå Žåãããããã§ãã
ãã®ãããªå ŽåãRector ã¯ããã¯ã©ã¹ã®ãªãŒãããŒãã倱æãããšèŠåããŸããããããã察å¿ãããã¡ã€ã«ãç¹å®ãããªãŒãããŒããã¹ã«æåã§è¿œå ããŸãã
çµæã確èªãã
ããããã©ã°ã€ã³ã®ãœãŒã¹ã³ãŒãã§ããããããã¹ã³ãŒãåãããïŒPHP 7.1 ã«ããŠã³ã°ã¬ãŒããããïŒããŒãžã§ã³ã§ãã
7 ã€ã®éããèŠã€ããŠãã ãã ðãïŒãã³ãããããŸããPrefixedByPoP ãæ€çŽ¢ããŠãã ãããïŒ
ãããŠãããæçµç㪠graphql-api.zip ãã©ã°ã€ã³ãã¡ã€ã«ã§ãããµã€ãã«ã€ã³ã¹ããŒã«ããæºåãã§ããŠããŸãã
以äžã§ããã圹ã«ç«ãŠãã°å¹žãã§ã ððªð